adspower-browser 1.0.1 → 2.0.0-beta.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/cli/index.js +2133 -0
- package/cwd/lib/main.min.js +2 -0
- package/package.json +23 -9
- package/sqlite/arm64/node_sqlite3.node +0 -0
- package/sqlite/ia32/node_sqlite3.node +0 -0
- package/sqlite/linux/node_sqlite3.node +0 -0
- package/sqlite/mac/node_sqlite3.node +0 -0
- package/sqlite/x64/node_sqlite3.node +0 -0
- package/build/cli.js +0 -1024
package/cli/index.js
ADDED
|
@@ -0,0 +1,2133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/index.ts
|
|
27
|
+
var import_commander = require("commander");
|
|
28
|
+
|
|
29
|
+
// src/store/index.ts
|
|
30
|
+
var Store = class {
|
|
31
|
+
apiKey;
|
|
32
|
+
baseUrl;
|
|
33
|
+
nodeEnv;
|
|
34
|
+
apiPort;
|
|
35
|
+
appPort;
|
|
36
|
+
intranet;
|
|
37
|
+
rpaPid;
|
|
38
|
+
rpaPlusPid;
|
|
39
|
+
aiPid;
|
|
40
|
+
status;
|
|
41
|
+
pid;
|
|
42
|
+
constructor() {
|
|
43
|
+
this.apiKey = "";
|
|
44
|
+
this.baseUrl = "";
|
|
45
|
+
this.nodeEnv = "";
|
|
46
|
+
this.apiPort = "";
|
|
47
|
+
this.appPort = "";
|
|
48
|
+
this.intranet = "";
|
|
49
|
+
this.rpaPid = "";
|
|
50
|
+
this.rpaPlusPid = "";
|
|
51
|
+
this.aiPid = "";
|
|
52
|
+
this.status = "stop";
|
|
53
|
+
this.pid = "";
|
|
54
|
+
}
|
|
55
|
+
getStoreValue(key) {
|
|
56
|
+
return this[key];
|
|
57
|
+
}
|
|
58
|
+
setStoreValue(key, value) {
|
|
59
|
+
this[key] = value;
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
this.apiKey = "";
|
|
63
|
+
this.baseUrl = "";
|
|
64
|
+
this.nodeEnv = "";
|
|
65
|
+
this.apiPort = "";
|
|
66
|
+
this.appPort = "";
|
|
67
|
+
this.intranet = "";
|
|
68
|
+
this.rpaPid = "";
|
|
69
|
+
this.rpaPlusPid = "";
|
|
70
|
+
this.aiPid = "";
|
|
71
|
+
this.status = "stop";
|
|
72
|
+
this.pid = "";
|
|
73
|
+
}
|
|
74
|
+
getAllStoreValue() {
|
|
75
|
+
return {
|
|
76
|
+
apiKey: this.apiKey,
|
|
77
|
+
baseUrl: this.baseUrl,
|
|
78
|
+
nodeEnv: this.nodeEnv,
|
|
79
|
+
apiPort: this.apiPort,
|
|
80
|
+
appPort: this.appPort,
|
|
81
|
+
intranet: this.intranet,
|
|
82
|
+
rpaPid: this.rpaPid,
|
|
83
|
+
rpaPlusPid: this.rpaPlusPid,
|
|
84
|
+
aiPid: this.aiPid,
|
|
85
|
+
status: this.status,
|
|
86
|
+
pid: this.pid
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var store = new Store();
|
|
91
|
+
|
|
92
|
+
// src/core/start.ts
|
|
93
|
+
var path2 = __toESM(require("path"));
|
|
94
|
+
var import_node_child_process2 = require("child_process");
|
|
95
|
+
|
|
96
|
+
// src/tools/index.ts
|
|
97
|
+
var os = __toESM(require("os"));
|
|
98
|
+
var path = __toESM(require("path"));
|
|
99
|
+
var fs = __toESM(require("fs"));
|
|
100
|
+
var crypto = __toESM(require("crypto"));
|
|
101
|
+
var util = __toESM(require("util"));
|
|
102
|
+
var import_node_child_process = require("child_process");
|
|
103
|
+
var import_colors = require("colors");
|
|
104
|
+
var import_fs_extra2 = require("fs-extra2");
|
|
105
|
+
var VERSION = "1.0.0";
|
|
106
|
+
var logError = (message) => {
|
|
107
|
+
console.error((0, import_colors.red)(message));
|
|
108
|
+
};
|
|
109
|
+
var logSuccess = (message) => {
|
|
110
|
+
console.log((0, import_colors.green)(message));
|
|
111
|
+
};
|
|
112
|
+
var logWarning = (message) => {
|
|
113
|
+
console.log((0, import_colors.yellow)(message));
|
|
114
|
+
};
|
|
115
|
+
var logInfo = (message) => {
|
|
116
|
+
console.log(message);
|
|
117
|
+
};
|
|
118
|
+
var sleepTime = (time) => new Promise((resolve) => {
|
|
119
|
+
setTimeout(() => {
|
|
120
|
+
resolve();
|
|
121
|
+
}, time);
|
|
122
|
+
});
|
|
123
|
+
var browsersKill = async () => {
|
|
124
|
+
await taskKillBrowser();
|
|
125
|
+
await taskKillFlowser();
|
|
126
|
+
};
|
|
127
|
+
var taskKillBrowser = () => new Promise((resolve) => {
|
|
128
|
+
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "SunBrowser"' : "taskkill -PID SunBrowser.exe";
|
|
129
|
+
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
130
|
+
if (err) {
|
|
131
|
+
}
|
|
132
|
+
resolve();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
var taskKillFlowser = () => new Promise((resolve) => {
|
|
136
|
+
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "FlowerBrowser"' : "taskkill -PID FlowerBrowser.exe";
|
|
137
|
+
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
138
|
+
if (err) {
|
|
139
|
+
}
|
|
140
|
+
resolve();
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
var getHomedir = () => {
|
|
144
|
+
return (typeof os.homedir == "function" ? os.homedir() : process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"]) || "~";
|
|
145
|
+
};
|
|
146
|
+
var getPidFileDir = () => {
|
|
147
|
+
const dir = path.join(getHomedir(), ".adspowerCli");
|
|
148
|
+
if (!fs.existsSync(dir)) {
|
|
149
|
+
(0, import_fs_extra2.ensureDirSync)(dir);
|
|
150
|
+
}
|
|
151
|
+
return dir;
|
|
152
|
+
};
|
|
153
|
+
var pidFileName = () => {
|
|
154
|
+
const md5 = crypto.createHash("md5").update(VERSION).digest("hex");
|
|
155
|
+
return md5;
|
|
156
|
+
};
|
|
157
|
+
var writePidFile = (config2) => {
|
|
158
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
159
|
+
(0, import_fs_extra2.outputJsonSync)(filePath, config2 || {});
|
|
160
|
+
};
|
|
161
|
+
var readPidFile = () => {
|
|
162
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
163
|
+
if (fs.existsSync(filePath)) {
|
|
164
|
+
return (0, import_fs_extra2.readJsonSync)(filePath);
|
|
165
|
+
}
|
|
166
|
+
return {};
|
|
167
|
+
};
|
|
168
|
+
var removePidFile = () => {
|
|
169
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
170
|
+
if (fs.existsSync(filePath)) {
|
|
171
|
+
(0, import_fs_extra2.removeSync)(filePath);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
var isRunning = (pid) => {
|
|
175
|
+
return new Promise((resolve) => {
|
|
176
|
+
if (pid) {
|
|
177
|
+
(0, import_node_child_process.exec)(
|
|
178
|
+
util.format(process.platform === "win32" ? 'tasklist /fi "PID eq %s" | findstr /i "node.exe"' : 'ps -f -p %s | grep "node"', pid),
|
|
179
|
+
function(err, stdout, stderr) {
|
|
180
|
+
resolve(!err && !!stdout.toString().trim());
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
} else {
|
|
184
|
+
resolve(false);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
var ensureBrowserPath = () => {
|
|
189
|
+
const dir = path.join(__dirname, "../cwd/source", ".browser");
|
|
190
|
+
if (!fs.existsSync(dir)) {
|
|
191
|
+
(0, import_fs_extra2.ensureDirSync)(dir);
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
var getApiKeyAndPort = (options) => {
|
|
195
|
+
const apiKey = options.apiKey;
|
|
196
|
+
const port = options.port;
|
|
197
|
+
if (apiKey && port) {
|
|
198
|
+
return {
|
|
199
|
+
apiKey,
|
|
200
|
+
port
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const result = {
|
|
204
|
+
apiKey,
|
|
205
|
+
port
|
|
206
|
+
};
|
|
207
|
+
const processInstance = readPidFile();
|
|
208
|
+
if (!apiKey && processInstance.apiKey) {
|
|
209
|
+
result.apiKey = processInstance.apiKey;
|
|
210
|
+
}
|
|
211
|
+
if (!port && processInstance.apiPort) {
|
|
212
|
+
result.port = processInstance.apiPort;
|
|
213
|
+
}
|
|
214
|
+
return result;
|
|
215
|
+
};
|
|
216
|
+
var hasRunning = async (options) => {
|
|
217
|
+
const { apiKey, port } = options;
|
|
218
|
+
if (apiKey && port) {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
const processInstance = readPidFile();
|
|
222
|
+
if (processInstance.pid) {
|
|
223
|
+
return await isRunning(processInstance.pid);
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
};
|
|
227
|
+
var loadingFramesList = {
|
|
228
|
+
default: ["|", "/", "-", "\\"],
|
|
229
|
+
frames: ["\u2596", "\u2597", "\u2598", "\u2599", "\u259A", "\u259B", "\u259C", "\u259D", "\u259E", "\u259F"],
|
|
230
|
+
dotFrames: ["\u2840", "\u2844", "\u2846", "\u2847", "\u284F", "\u285F", "\u287F", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28E0", "\u2880"]
|
|
231
|
+
};
|
|
232
|
+
var createLoading = (text) => {
|
|
233
|
+
if (!process.stdout.isTTY) {
|
|
234
|
+
return {
|
|
235
|
+
stop() {
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
let index = 0;
|
|
240
|
+
const frames = loadingFramesList.default;
|
|
241
|
+
process.stdout.write(`${frames[index]} ${text}`);
|
|
242
|
+
const timer = setInterval(() => {
|
|
243
|
+
index = (index + 1) % frames.length;
|
|
244
|
+
process.stdout.write(`\r${frames[index]} ${text}`);
|
|
245
|
+
}, 120);
|
|
246
|
+
return {
|
|
247
|
+
stop() {
|
|
248
|
+
clearInterval(timer);
|
|
249
|
+
process.stdout.write(`\r${" ".repeat(text.length + 2)}\r`);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
};
|
|
253
|
+
var initSqlite3 = () => {
|
|
254
|
+
const sqliteFile = path.join(__dirname, "../cwd/lib", "node_sqlite3.node");
|
|
255
|
+
if (fs.existsSync(sqliteFile)) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
const isMac = process.platform === "darwin";
|
|
259
|
+
const isLinux = process.platform === "linux";
|
|
260
|
+
const is32 = process.arch === "ia32";
|
|
261
|
+
const isArm = process.arch === "arm64";
|
|
262
|
+
const isX64 = process.arch === "x64";
|
|
263
|
+
const macFolder = isArm ? "arm64" : "mac";
|
|
264
|
+
const winFolder = is32 ? "ia32" : "x64";
|
|
265
|
+
const linuxFolder = isLinux && isX64 && "linux";
|
|
266
|
+
const sqliteFolder = isMac ? macFolder : isLinux ? linuxFolder : winFolder;
|
|
267
|
+
const dir = path.join(__dirname, `../sqlite/${sqliteFolder}`);
|
|
268
|
+
if (!fs.existsSync(dir)) {
|
|
269
|
+
throw new Error(`SQLite folder not found: ${dir}`);
|
|
270
|
+
} else {
|
|
271
|
+
const sqliteFile2 = path.join(dir, "node_sqlite3.node");
|
|
272
|
+
const cwdPath = path.join(__dirname, "../cwd/lib");
|
|
273
|
+
(0, import_fs_extra2.copySync)(sqliteFile2, path.join(cwdPath, "node_sqlite3.node"));
|
|
274
|
+
logSuccess(`[i] SQLite file initialized successfully!`);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// src/core/start.ts
|
|
279
|
+
var getEnv = () => {
|
|
280
|
+
const env = {
|
|
281
|
+
...process.env,
|
|
282
|
+
// 系统的环境变量信息
|
|
283
|
+
API_KEY: store.getStoreValue("apiKey"),
|
|
284
|
+
IS_CLOUD_BROWSER: true
|
|
285
|
+
// 云浏览器场景预留标识
|
|
286
|
+
};
|
|
287
|
+
if (store.getStoreValue("baseUrl")) {
|
|
288
|
+
env.BASE_URL = store.getStoreValue("baseUrl");
|
|
289
|
+
}
|
|
290
|
+
if (store.getStoreValue("nodeEnv")) {
|
|
291
|
+
env.NODE_ENV = store.getStoreValue("nodeEnv");
|
|
292
|
+
}
|
|
293
|
+
return env;
|
|
294
|
+
};
|
|
295
|
+
var startChild = (type) => {
|
|
296
|
+
let timer;
|
|
297
|
+
let child = null;
|
|
298
|
+
return new Promise(async (resolve, reject) => {
|
|
299
|
+
initSqlite3();
|
|
300
|
+
const processInstance = readPidFile();
|
|
301
|
+
if (processInstance && processInstance.pid) {
|
|
302
|
+
const isRun = await isRunning(processInstance.pid);
|
|
303
|
+
removePidFile();
|
|
304
|
+
if (isRun) {
|
|
305
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
306
|
+
await sleepTime(1e3);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
const env = Object.fromEntries(
|
|
310
|
+
Object.entries(getEnv()).map(([key, value]) => [key, value == null ? value : String(value)])
|
|
311
|
+
);
|
|
312
|
+
try {
|
|
313
|
+
const mainJs = path2.join(__dirname, "../cwd/lib", "main.min.js");
|
|
314
|
+
child = (0, import_node_child_process2.fork)(mainJs, {
|
|
315
|
+
env,
|
|
316
|
+
detached: true,
|
|
317
|
+
stdio: ["ignore", "ignore", "ignore", "ipc"]
|
|
318
|
+
});
|
|
319
|
+
ensureBrowserPath();
|
|
320
|
+
store.setStoreValue("status", "starting");
|
|
321
|
+
logSuccess(`[i] Adspower program is starting...`);
|
|
322
|
+
store.setStoreValue("pid", child?.pid?.toString() || "");
|
|
323
|
+
let isAppPortOk = false;
|
|
324
|
+
writePidFile(store.getAllStoreValue());
|
|
325
|
+
child.on("message", async (msg) => {
|
|
326
|
+
const text = String(msg);
|
|
327
|
+
if (text.indexOf("SERVER_PORT_$$_") === 0 && !isAppPortOk) {
|
|
328
|
+
const port = text.replace("SERVER_PORT_$$_", "").trim();
|
|
329
|
+
store.setStoreValue("appPort", port);
|
|
330
|
+
isAppPortOk = true;
|
|
331
|
+
}
|
|
332
|
+
if (text.indexOf("START_API_SERVER_SUCCESS_$$_") === 0) {
|
|
333
|
+
const port = text.replace("START_API_SERVER_SUCCESS_$$_", "").trim();
|
|
334
|
+
store.setStoreValue("apiPort", port);
|
|
335
|
+
logSuccess(`Server running at:`);
|
|
336
|
+
logSuccess(` - local: http://local.adspower.net:${port}`);
|
|
337
|
+
writePidFile(store.getAllStoreValue());
|
|
338
|
+
if (child) {
|
|
339
|
+
child.disconnect();
|
|
340
|
+
child.unref();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (text.indexOf("START_API_SERVER_FAIL_$$_") === 0) {
|
|
344
|
+
const serverMsg = text.replace("START_API_SERVER_FAIL_$$_", "").split("_").filter(Boolean);
|
|
345
|
+
if (serverMsg[0]) {
|
|
346
|
+
logError(`ERROR - ${serverMsg[0]}`);
|
|
347
|
+
}
|
|
348
|
+
if (serverMsg[1]) {
|
|
349
|
+
logError(`ERROR - ${serverMsg[1]}`);
|
|
350
|
+
}
|
|
351
|
+
process.exit(0);
|
|
352
|
+
}
|
|
353
|
+
if (text === "start") {
|
|
354
|
+
clearTimeout(timer);
|
|
355
|
+
resolve();
|
|
356
|
+
store.setStoreValue("status", "doing");
|
|
357
|
+
writePidFile(store.getAllStoreValue());
|
|
358
|
+
}
|
|
359
|
+
if (text === "restart") {
|
|
360
|
+
child && child.kill("SIGKILL");
|
|
361
|
+
store.setStoreValue("status", "restarting");
|
|
362
|
+
startChild("2").catch(() => {
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
if (text.indexOf("INTRANET_$$_") > -1) {
|
|
366
|
+
const arr = text.split("_$$_");
|
|
367
|
+
if (arr && arr[1]) {
|
|
368
|
+
store.setStoreValue("intranet", arr[1]);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (text === "browser-kill") {
|
|
372
|
+
await browsersKill();
|
|
373
|
+
}
|
|
374
|
+
if (text.indexOf("RPA_PROCESS_PID_") > -1) {
|
|
375
|
+
const rpaPid = text.replace("RPA_PROCESS_PID_", "");
|
|
376
|
+
store.setStoreValue("rpaPid", rpaPid);
|
|
377
|
+
}
|
|
378
|
+
if (text.indexOf("RPA_PLUS_PROCESS_PID_") > -1) {
|
|
379
|
+
const rpaPlusPid = text.replace("RPA_PLUS_PROCESS_PID_", "");
|
|
380
|
+
store.setStoreValue("rpaPlusPid", rpaPlusPid);
|
|
381
|
+
}
|
|
382
|
+
if (text.indexOf("AI_PROCESS_PID_") > -1) {
|
|
383
|
+
const aiPid = text.replace("AI_PROCESS_PID_", "");
|
|
384
|
+
store.setStoreValue("aiPid", aiPid);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
child.on("error", (err) => {
|
|
388
|
+
logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${err.message}`);
|
|
389
|
+
store.setStoreValue("status", "stop");
|
|
390
|
+
store.clear();
|
|
391
|
+
removePidFile();
|
|
392
|
+
process.exit(0);
|
|
393
|
+
});
|
|
394
|
+
child.on("exit", async (code, signal) => {
|
|
395
|
+
if (signal === "SIGKILL") {
|
|
396
|
+
await browsersKill();
|
|
397
|
+
store.clear();
|
|
398
|
+
removePidFile();
|
|
399
|
+
} else {
|
|
400
|
+
child = null;
|
|
401
|
+
await sleepTime(500);
|
|
402
|
+
startChild("2").then(() => {
|
|
403
|
+
}).catch(() => {
|
|
404
|
+
logError("[!] Restart failed");
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
timer = setTimeout(() => {
|
|
409
|
+
child && child.kill("SIGKILL");
|
|
410
|
+
child = null;
|
|
411
|
+
store.setStoreValue("status", "stop");
|
|
412
|
+
logError("[!] Start Timeout");
|
|
413
|
+
reject("Start Timeout");
|
|
414
|
+
}, 30 * 1e3);
|
|
415
|
+
} catch (error) {
|
|
416
|
+
clearTimeout(timer);
|
|
417
|
+
reject(error);
|
|
418
|
+
child = null;
|
|
419
|
+
store.clear();
|
|
420
|
+
logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
};
|
|
424
|
+
var stopChild = async () => {
|
|
425
|
+
const processInstance = readPidFile();
|
|
426
|
+
if (processInstance.pid) {
|
|
427
|
+
const isRun = await isRunning(processInstance.pid);
|
|
428
|
+
try {
|
|
429
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
430
|
+
removePidFile();
|
|
431
|
+
} catch (error) {
|
|
432
|
+
try {
|
|
433
|
+
await sleepTime(2e3);
|
|
434
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
435
|
+
removePidFile();
|
|
436
|
+
} catch (error2) {
|
|
437
|
+
logError(`[!] Stop child fail: ${error2 instanceof Error ? error2.message : JSON.stringify(error2)}`);
|
|
438
|
+
if (isRun) {
|
|
439
|
+
logWarning(`[!] Please manually close the browser process: ${processInstance.pid}`);
|
|
440
|
+
}
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
logSuccess("[i] Adspower program is stopped");
|
|
445
|
+
} else {
|
|
446
|
+
logInfo("[i] No running adspower program");
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
var restartChild = async () => {
|
|
450
|
+
const processInstance = readPidFile();
|
|
451
|
+
if (processInstance.pid) {
|
|
452
|
+
const apiKey = processInstance.apiKey;
|
|
453
|
+
const baseUrl = processInstance.baseUrl;
|
|
454
|
+
const nodeEnv = processInstance.nodeEnv;
|
|
455
|
+
await stopChild();
|
|
456
|
+
await sleepTime(1e3);
|
|
457
|
+
store.setStoreValue("apiKey", apiKey);
|
|
458
|
+
store.setStoreValue("baseUrl", baseUrl);
|
|
459
|
+
store.setStoreValue("nodeEnv", nodeEnv);
|
|
460
|
+
await startChild().then(() => {
|
|
461
|
+
logSuccess("[i] Adspower program is restarted");
|
|
462
|
+
}).catch((error) => {
|
|
463
|
+
logError(`[!] Restart failed: ${error.message}`);
|
|
464
|
+
});
|
|
465
|
+
} else {
|
|
466
|
+
logInfo("[i] No running adspower program");
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var getChildStatus = async () => {
|
|
470
|
+
const processInstance = readPidFile();
|
|
471
|
+
if (processInstance.pid) {
|
|
472
|
+
const isRun = await isRunning(processInstance.pid);
|
|
473
|
+
if (!isRun) {
|
|
474
|
+
removePidFile();
|
|
475
|
+
logInfo("[i] Adspower program is not running");
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const status = processInstance.status;
|
|
479
|
+
if (status === "starting") {
|
|
480
|
+
logSuccess("[i] Adspower program is starting...");
|
|
481
|
+
} else if (status === "doing" && processInstance.apiPort) {
|
|
482
|
+
logSuccess("[i] Adspower program is running at:");
|
|
483
|
+
logSuccess(` - http://local.adspower.net:${processInstance.apiPort}`);
|
|
484
|
+
} else if (status === "stop") {
|
|
485
|
+
logInfo("[i] Adspower program is stopped");
|
|
486
|
+
} else {
|
|
487
|
+
logInfo("[i] Adspower program is not started");
|
|
488
|
+
}
|
|
489
|
+
} else {
|
|
490
|
+
logInfo("[i] Adspower program is not running");
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
// src/index.ts
|
|
495
|
+
var import_colors2 = require("colors");
|
|
496
|
+
|
|
497
|
+
// ../core/src/constants/api.ts
|
|
498
|
+
var import_axios = __toESM(require("axios"));
|
|
499
|
+
|
|
500
|
+
// ../core/src/constants/config.ts
|
|
501
|
+
function parseArgs() {
|
|
502
|
+
const args = process.argv;
|
|
503
|
+
let port;
|
|
504
|
+
let apiKey;
|
|
505
|
+
for (let i = 0; i < args.length; i++) {
|
|
506
|
+
if (args[i] === "--port" && i + 1 < args.length) {
|
|
507
|
+
port = args[i + 1];
|
|
508
|
+
}
|
|
509
|
+
if (args[i] === "--api-key" && i + 1 < args.length) {
|
|
510
|
+
apiKey = args[i + 1];
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
port: port || process.env.PORT || "50326",
|
|
515
|
+
apiKey: apiKey || process.env.API_KEY
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
var config = parseArgs();
|
|
519
|
+
var updateConfig = (apiKey, port) => {
|
|
520
|
+
if (apiKey) {
|
|
521
|
+
config.apiKey = apiKey;
|
|
522
|
+
}
|
|
523
|
+
if (port) {
|
|
524
|
+
config.port = port;
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
var PORT = config.port;
|
|
528
|
+
var API_KEY = config.apiKey;
|
|
529
|
+
var CONFIG = config;
|
|
530
|
+
|
|
531
|
+
// ../core/src/constants/api.ts
|
|
532
|
+
var LOCAL_API_BASE = `http://127.0.0.1:${PORT}`;
|
|
533
|
+
var getLocalApiBase = () => {
|
|
534
|
+
return `http://127.0.0.1:${CONFIG.port}`;
|
|
535
|
+
};
|
|
536
|
+
var API_ENDPOINTS = {
|
|
537
|
+
STATUS: "/status",
|
|
538
|
+
START_BROWSER: "/api/v2/browser-profile/start",
|
|
539
|
+
CLOSE_BROWSER: "/api/v2/browser-profile/stop",
|
|
540
|
+
CREATE_BROWSER: "/api/v2/browser-profile/create",
|
|
541
|
+
GET_BROWSER_LIST: "/api/v2/browser-profile/list",
|
|
542
|
+
UPDATE_BROWSER: "/api/v2/browser-profile/update",
|
|
543
|
+
DELETE_BROWSER: "/api/v2/browser-profile/delete",
|
|
544
|
+
GET_PROFILE_COOKIES: "/api/v2/browser-profile/cookies",
|
|
545
|
+
GET_PROFILE_UA: "/api/v2/browser-profile/ua",
|
|
546
|
+
CLOSE_ALL_PROFILES: "/api/v2/browser-profile/stop-all",
|
|
547
|
+
NEW_FINGERPRINT: "/api/v2/browser-profile/new-fingerprint",
|
|
548
|
+
DELETE_CACHE_V2: "/api/v2/browser-profile/delete-cache",
|
|
549
|
+
SHARE_PROFILE: "/api/v2/browser-profile/share",
|
|
550
|
+
GET_BROWSER_ACTIVE: "/api/v2/browser-profile/active",
|
|
551
|
+
CREATE_PROXY: "/api/v2/proxy-list/create",
|
|
552
|
+
UPDATE_PROXY: "/api/v2/proxy-list/update",
|
|
553
|
+
GET_PROXY_LIST: "/api/v2/proxy-list/list",
|
|
554
|
+
DELETE_PROXY: "/api/v2/proxy-list/delete",
|
|
555
|
+
GET_OPENED_BROWSER: "/api/v1/browser/local-active",
|
|
556
|
+
GET_CLOUD_ACTIVE: "/api/v1/browser/cloud-active",
|
|
557
|
+
MOVE_BROWSER: "/api/v1/user/regroup",
|
|
558
|
+
GET_GROUP_LIST: "/api/v1/group/list",
|
|
559
|
+
CREATE_GROUP: "/api/v1/group/create",
|
|
560
|
+
UPDATE_GROUP: "/api/v1/group/update",
|
|
561
|
+
GET_APPLICATION_LIST: "/api/v2/category/list",
|
|
562
|
+
GET_TAG_LIST: "/api/v2/browser-tags/list",
|
|
563
|
+
CREATE_TAG: "/api/v2/browser-tags/create",
|
|
564
|
+
UPDATE_TAG: "/api/v2/browser-tags/update",
|
|
565
|
+
DELETE_TAG: "/api/v2/browser-tags/delete",
|
|
566
|
+
DOWNLOAD_KERNEL: "/api/v2/browser-profile/download-kernel",
|
|
567
|
+
GET_KERNEL_LIST: "/api/v2/browser-profile/kernels",
|
|
568
|
+
UPDATE_PATCH: "/api/v2/browser-profile/update-patch"
|
|
569
|
+
};
|
|
570
|
+
var apiClient = import_axios.default.create({
|
|
571
|
+
headers: API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {}
|
|
572
|
+
});
|
|
573
|
+
var getApiClient = () => {
|
|
574
|
+
return import_axios.default.create({
|
|
575
|
+
headers: CONFIG.apiKey ? { "Authorization": `Bearer ${CONFIG.apiKey}` } : {}
|
|
576
|
+
});
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// ../core/src/utils/requestBuilder.ts
|
|
580
|
+
function buildRequestBody(params) {
|
|
581
|
+
const requestBody = {};
|
|
582
|
+
const basicFields = {
|
|
583
|
+
groupId: "group_id",
|
|
584
|
+
username: "username",
|
|
585
|
+
password: "password",
|
|
586
|
+
cookie: "cookie",
|
|
587
|
+
fakey: "fakey",
|
|
588
|
+
name: "name",
|
|
589
|
+
platform: "platform",
|
|
590
|
+
remark: "remark",
|
|
591
|
+
proxyid: "proxyid",
|
|
592
|
+
repeatConfig: "repeat_config",
|
|
593
|
+
ignoreCookieError: "ignore_cookie_error",
|
|
594
|
+
tabs: "tabs",
|
|
595
|
+
ip: "ip",
|
|
596
|
+
country: "country",
|
|
597
|
+
region: "region",
|
|
598
|
+
city: "city",
|
|
599
|
+
ipchecker: "ipchecker",
|
|
600
|
+
categoryId: "category_id",
|
|
601
|
+
launchArgs: "launch_args",
|
|
602
|
+
profileId: "profile_id",
|
|
603
|
+
profileTagIds: "profile_tag_ids",
|
|
604
|
+
tagsUpdateType: "tags_update_type"
|
|
605
|
+
};
|
|
606
|
+
Object.entries(basicFields).forEach(([paramKey, key]) => {
|
|
607
|
+
const value = params[paramKey];
|
|
608
|
+
if (value !== void 0) {
|
|
609
|
+
requestBody[key] = value;
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
if (params.userProxyConfig) {
|
|
613
|
+
const proxyConfig = buildNestedConfig(params.userProxyConfig);
|
|
614
|
+
if (Object.keys(proxyConfig).length > 0) {
|
|
615
|
+
requestBody.user_proxy_config = proxyConfig;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (params.fingerprintConfig) {
|
|
619
|
+
const fpConfig = buildNestedConfig(params.fingerprintConfig);
|
|
620
|
+
if (Object.keys(fpConfig).length > 0) {
|
|
621
|
+
requestBody.fingerprint_config = fpConfig;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return requestBody;
|
|
625
|
+
}
|
|
626
|
+
function buildNestedConfig(config2) {
|
|
627
|
+
const result = {};
|
|
628
|
+
Object.entries(config2).forEach(([key, value]) => {
|
|
629
|
+
if (value !== void 0) {
|
|
630
|
+
if (typeof value === "object" && value !== null) {
|
|
631
|
+
const nestedConfig = buildNestedConfig(value);
|
|
632
|
+
if (Object.keys(nestedConfig).length > 0) {
|
|
633
|
+
result[key] = nestedConfig;
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
result[key] = value;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
return result;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// ../core/src/handlers/browser.ts
|
|
644
|
+
var browserHandlers = {
|
|
645
|
+
async openBrowser({ profileNo, profileId, ipTab, launchArgs, clearCacheAfterClosing, cdpMask }) {
|
|
646
|
+
const requestBody = {};
|
|
647
|
+
if (profileId) {
|
|
648
|
+
requestBody.profile_id = profileId;
|
|
649
|
+
}
|
|
650
|
+
if (profileNo) {
|
|
651
|
+
requestBody.profile_no = profileNo;
|
|
652
|
+
}
|
|
653
|
+
if (ipTab) {
|
|
654
|
+
requestBody.ip_tab = ipTab;
|
|
655
|
+
}
|
|
656
|
+
if (launchArgs) {
|
|
657
|
+
requestBody.launch_args = launchArgs;
|
|
658
|
+
}
|
|
659
|
+
if (clearCacheAfterClosing) {
|
|
660
|
+
requestBody.delete_cache = clearCacheAfterClosing;
|
|
661
|
+
}
|
|
662
|
+
if (cdpMask) {
|
|
663
|
+
requestBody.cdp_mask = cdpMask;
|
|
664
|
+
}
|
|
665
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.START_BROWSER}`, requestBody);
|
|
666
|
+
if (response.data.code === 0) {
|
|
667
|
+
return `Browser opened successfully with: ${Object.entries(response.data.data).map(([key, value]) => {
|
|
668
|
+
if (value && typeof value === "object") {
|
|
669
|
+
return Object.entries(value).map(([key2, value2]) => `ws.${key2}: ${value2}`).join("\n");
|
|
670
|
+
}
|
|
671
|
+
return `${key}: ${value}`;
|
|
672
|
+
}).join("\n")}`;
|
|
673
|
+
}
|
|
674
|
+
throw new Error(`Failed to open browser: ${response.data.msg}`);
|
|
675
|
+
},
|
|
676
|
+
async closeBrowser({ profileId, profileNo }) {
|
|
677
|
+
const requestBody = {};
|
|
678
|
+
if (profileId) {
|
|
679
|
+
requestBody.profile_id = profileId;
|
|
680
|
+
}
|
|
681
|
+
if (profileNo) {
|
|
682
|
+
requestBody.profile_no = profileNo;
|
|
683
|
+
}
|
|
684
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_BROWSER}`, requestBody);
|
|
685
|
+
if (response.data.code === 0) {
|
|
686
|
+
return "Browser closed successfully";
|
|
687
|
+
}
|
|
688
|
+
throw new Error(`Failed to close browser: ${response.data.msg}`);
|
|
689
|
+
},
|
|
690
|
+
async createBrowser(params) {
|
|
691
|
+
const requestBody = buildRequestBody(params);
|
|
692
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_BROWSER}`, requestBody);
|
|
693
|
+
if (response.data.code === 0) {
|
|
694
|
+
return `Browser created successfully with: ${Object.entries(response.data.data).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
695
|
+
}
|
|
696
|
+
throw new Error(`Failed to create browser: ${response.data.msg}`);
|
|
697
|
+
},
|
|
698
|
+
async updateBrowser(params) {
|
|
699
|
+
const requestBody = buildRequestBody(params);
|
|
700
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_BROWSER}`, requestBody);
|
|
701
|
+
if (response.data.code === 0) {
|
|
702
|
+
return `Browser updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
703
|
+
}
|
|
704
|
+
throw new Error(`Failed to update browser: ${response.data.msg}`);
|
|
705
|
+
},
|
|
706
|
+
async deleteBrowser({ profileIds }) {
|
|
707
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_BROWSER}`, {
|
|
708
|
+
profile_id: profileIds
|
|
709
|
+
});
|
|
710
|
+
if (response.data.code === 0) {
|
|
711
|
+
return `Browsers deleted successfully: ${profileIds.join(", ")}`;
|
|
712
|
+
}
|
|
713
|
+
throw new Error(`Failed to delete browsers: ${response.data.msg}`);
|
|
714
|
+
},
|
|
715
|
+
async getBrowserList(params) {
|
|
716
|
+
const { groupId, limit, page, profileId, profileNo, sortType, sortOrder, tag_ids, tags_filter, name, name_filter } = params;
|
|
717
|
+
const requestBody = {};
|
|
718
|
+
if (limit !== void 0) {
|
|
719
|
+
requestBody.limit = limit;
|
|
720
|
+
}
|
|
721
|
+
if (page !== void 0) {
|
|
722
|
+
requestBody.page = page;
|
|
723
|
+
}
|
|
724
|
+
if (profileId && profileId.length > 0) {
|
|
725
|
+
requestBody.profile_id = profileId;
|
|
726
|
+
}
|
|
727
|
+
if (profileNo && profileNo.length > 0) {
|
|
728
|
+
requestBody.profile_no = profileNo;
|
|
729
|
+
}
|
|
730
|
+
if (groupId !== void 0) {
|
|
731
|
+
requestBody.group_id = groupId;
|
|
732
|
+
}
|
|
733
|
+
if (sortType) {
|
|
734
|
+
requestBody.sort_type = sortType;
|
|
735
|
+
}
|
|
736
|
+
if (sortOrder) {
|
|
737
|
+
requestBody.sort_order = sortOrder;
|
|
738
|
+
}
|
|
739
|
+
if (tag_ids && tag_ids.length > 0) {
|
|
740
|
+
requestBody.tag_ids = tag_ids;
|
|
741
|
+
}
|
|
742
|
+
if (tags_filter) {
|
|
743
|
+
requestBody.tags_filter = tags_filter;
|
|
744
|
+
}
|
|
745
|
+
if (name) {
|
|
746
|
+
requestBody.name = name;
|
|
747
|
+
}
|
|
748
|
+
if (name_filter) {
|
|
749
|
+
requestBody.name_filter = name_filter;
|
|
750
|
+
}
|
|
751
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_LIST}`, requestBody);
|
|
752
|
+
if (response.data.code === 0) {
|
|
753
|
+
return `Browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
754
|
+
}
|
|
755
|
+
throw new Error(`Failed to get browser list: ${response.data.msg}`);
|
|
756
|
+
},
|
|
757
|
+
async getOpenedBrowser() {
|
|
758
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_OPENED_BROWSER}`);
|
|
759
|
+
if (response.data.code === 0) {
|
|
760
|
+
return `Opened browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
761
|
+
}
|
|
762
|
+
throw new Error(`Failed to get opened browsers: ${response.data.msg}`);
|
|
763
|
+
},
|
|
764
|
+
async moveBrowser({ groupId, userIds }) {
|
|
765
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.MOVE_BROWSER}`, {
|
|
766
|
+
group_id: groupId,
|
|
767
|
+
user_ids: userIds
|
|
768
|
+
});
|
|
769
|
+
if (response.data.code === 0) {
|
|
770
|
+
return `Browsers moved successfully to group ${groupId}: ${userIds.join(", ")}`;
|
|
771
|
+
}
|
|
772
|
+
throw new Error(`Failed to move browsers: ${response.data.msg}`);
|
|
773
|
+
},
|
|
774
|
+
async getProfileCookies({ profileId, profileNo }) {
|
|
775
|
+
const params = new URLSearchParams();
|
|
776
|
+
if (profileId) {
|
|
777
|
+
params.set("profile_id", profileId);
|
|
778
|
+
}
|
|
779
|
+
if (profileNo) {
|
|
780
|
+
params.set("profile_no", profileNo);
|
|
781
|
+
}
|
|
782
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params });
|
|
783
|
+
if (response.data.code === 0) {
|
|
784
|
+
return `Profile cookies: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
785
|
+
}
|
|
786
|
+
throw new Error(`Failed to get profile cookies: ${response.data.msg}`);
|
|
787
|
+
},
|
|
788
|
+
async getProfileUa({ profileId, profileNo }) {
|
|
789
|
+
const requestBody = {};
|
|
790
|
+
if (profileId && profileId.length > 0) {
|
|
791
|
+
requestBody.profile_id = profileId;
|
|
792
|
+
}
|
|
793
|
+
if (profileNo && profileNo.length > 0) {
|
|
794
|
+
requestBody.profile_no = profileNo;
|
|
795
|
+
}
|
|
796
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_UA}`, requestBody);
|
|
797
|
+
if (response.data.code === 0) {
|
|
798
|
+
return `Profile User-Agent: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
799
|
+
}
|
|
800
|
+
throw new Error(`Failed to get profile User-Agent: ${response.data.msg}`);
|
|
801
|
+
},
|
|
802
|
+
async closeAllProfiles(_params) {
|
|
803
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_ALL_PROFILES}`, {});
|
|
804
|
+
if (response.data.code === 0) {
|
|
805
|
+
return "All profiles closed successfully";
|
|
806
|
+
}
|
|
807
|
+
throw new Error(`Failed to close all profiles: ${response.data.msg}`);
|
|
808
|
+
},
|
|
809
|
+
async newFingerprint({ profileId, profileNo }) {
|
|
810
|
+
const requestBody = {};
|
|
811
|
+
if (profileId && profileId.length > 0) {
|
|
812
|
+
requestBody.profile_id = profileId;
|
|
813
|
+
}
|
|
814
|
+
if (profileNo && profileNo.length > 0) {
|
|
815
|
+
requestBody.profile_no = profileNo;
|
|
816
|
+
}
|
|
817
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.NEW_FINGERPRINT}`, requestBody);
|
|
818
|
+
if (response.data.code === 0) {
|
|
819
|
+
return `New fingerprint created: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
820
|
+
}
|
|
821
|
+
throw new Error(`Failed to create new fingerprint: ${response.data.msg}`);
|
|
822
|
+
},
|
|
823
|
+
async deleteCacheV2({ profileIds, type }) {
|
|
824
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_CACHE_V2}`, {
|
|
825
|
+
profile_id: profileIds,
|
|
826
|
+
type
|
|
827
|
+
});
|
|
828
|
+
if (response.data.code === 0) {
|
|
829
|
+
return `Cache deleted successfully for profiles: ${profileIds.join(", ")}`;
|
|
830
|
+
}
|
|
831
|
+
throw new Error(`Failed to delete cache: ${response.data.msg}`);
|
|
832
|
+
},
|
|
833
|
+
async shareProfile({ profileIds, receiver, shareType, content }) {
|
|
834
|
+
const requestBody = {
|
|
835
|
+
profile_id: profileIds,
|
|
836
|
+
receiver
|
|
837
|
+
};
|
|
838
|
+
if (shareType !== void 0) {
|
|
839
|
+
requestBody.share_type = shareType;
|
|
840
|
+
}
|
|
841
|
+
if (content !== void 0) {
|
|
842
|
+
requestBody.content = content;
|
|
843
|
+
}
|
|
844
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.SHARE_PROFILE}`, requestBody);
|
|
845
|
+
if (response.data.code === 0) {
|
|
846
|
+
return `Profiles shared successfully: ${profileIds.join(", ")}`;
|
|
847
|
+
}
|
|
848
|
+
throw new Error(`Failed to share profiles: ${response.data.msg}`);
|
|
849
|
+
},
|
|
850
|
+
async getBrowserActive({ profileId, profileNo }) {
|
|
851
|
+
const params = new URLSearchParams();
|
|
852
|
+
if (profileId) {
|
|
853
|
+
params.set("profile_id", profileId);
|
|
854
|
+
}
|
|
855
|
+
if (profileNo) {
|
|
856
|
+
params.set("profile_no", profileNo);
|
|
857
|
+
}
|
|
858
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params });
|
|
859
|
+
if (response.data.code === 0) {
|
|
860
|
+
return `Browser active info: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
861
|
+
}
|
|
862
|
+
throw new Error(`Failed to get browser active: ${response.data.msg}`);
|
|
863
|
+
},
|
|
864
|
+
async getCloudActive({ userIds }) {
|
|
865
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, {
|
|
866
|
+
user_ids: userIds
|
|
867
|
+
});
|
|
868
|
+
if (response.data.code === 0) {
|
|
869
|
+
return `Cloud active browsers: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
870
|
+
}
|
|
871
|
+
throw new Error(`Failed to get cloud active browsers: ${response.data.msg}`);
|
|
872
|
+
}
|
|
873
|
+
};
|
|
874
|
+
|
|
875
|
+
// ../core/src/handlers/group.ts
|
|
876
|
+
var groupHandlers = {
|
|
877
|
+
async createGroup({ groupName, remark }) {
|
|
878
|
+
const requestBody = {
|
|
879
|
+
group_name: groupName
|
|
880
|
+
};
|
|
881
|
+
if (remark !== void 0) {
|
|
882
|
+
requestBody.remark = remark;
|
|
883
|
+
}
|
|
884
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_GROUP}`, requestBody);
|
|
885
|
+
if (response.data.code === 0) {
|
|
886
|
+
return `Group created successfully with name: ${groupName}${remark ? `, remark: ${remark}` : ""}`;
|
|
887
|
+
}
|
|
888
|
+
throw new Error(`Failed to create group: ${response.data.msg}`);
|
|
889
|
+
},
|
|
890
|
+
async updateGroup({ groupId, groupName, remark }) {
|
|
891
|
+
const requestBody = {
|
|
892
|
+
group_id: groupId,
|
|
893
|
+
group_name: groupName
|
|
894
|
+
};
|
|
895
|
+
if (remark !== void 0) {
|
|
896
|
+
requestBody.remark = remark;
|
|
897
|
+
}
|
|
898
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_GROUP}`, requestBody);
|
|
899
|
+
if (response.data.code === 0) {
|
|
900
|
+
return `Group updated successfully with id: ${groupId}, name: ${groupName}${remark !== void 0 ? `, remark: ${remark === null ? "(cleared)" : remark}` : ""}`;
|
|
901
|
+
}
|
|
902
|
+
throw new Error(`Failed to update group: ${response.data.msg}`);
|
|
903
|
+
},
|
|
904
|
+
async getGroupList({ groupName, size, page }) {
|
|
905
|
+
const params = new URLSearchParams();
|
|
906
|
+
if (groupName) {
|
|
907
|
+
params.set("group_name", groupName);
|
|
908
|
+
}
|
|
909
|
+
if (size) {
|
|
910
|
+
params.set("page_size", size.toString());
|
|
911
|
+
}
|
|
912
|
+
if (page) {
|
|
913
|
+
params.set("page", page.toString());
|
|
914
|
+
}
|
|
915
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_GROUP_LIST}`, { params });
|
|
916
|
+
return `Group list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// ../core/src/handlers/application.ts
|
|
921
|
+
var applicationHandlers = {
|
|
922
|
+
async checkStatus() {
|
|
923
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.STATUS}`);
|
|
924
|
+
return `Connection status: ${JSON.stringify(response.data, null, 2)}`;
|
|
925
|
+
},
|
|
926
|
+
async getApplicationList({ category_id, page, limit }) {
|
|
927
|
+
const params = new URLSearchParams();
|
|
928
|
+
if (category_id) {
|
|
929
|
+
params.set("category_id", category_id);
|
|
930
|
+
}
|
|
931
|
+
if (page !== void 0) {
|
|
932
|
+
params.set("page", page.toString());
|
|
933
|
+
}
|
|
934
|
+
if (limit !== void 0) {
|
|
935
|
+
params.set("limit", limit.toString());
|
|
936
|
+
}
|
|
937
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params });
|
|
938
|
+
return `Application list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
// ../core/src/handlers/proxy.ts
|
|
943
|
+
function buildProxyRequestBody(params) {
|
|
944
|
+
const requestBody = {};
|
|
945
|
+
if (params.proxyId) {
|
|
946
|
+
requestBody.proxy_id = params.proxyId;
|
|
947
|
+
}
|
|
948
|
+
if (params.type !== void 0) {
|
|
949
|
+
requestBody.type = params.type;
|
|
950
|
+
}
|
|
951
|
+
if (params.host !== void 0) {
|
|
952
|
+
requestBody.host = params.host;
|
|
953
|
+
}
|
|
954
|
+
if (params.port !== void 0) {
|
|
955
|
+
requestBody.port = params.port;
|
|
956
|
+
}
|
|
957
|
+
if (params.user !== void 0) {
|
|
958
|
+
requestBody.user = params.user;
|
|
959
|
+
}
|
|
960
|
+
if (params.password !== void 0) {
|
|
961
|
+
requestBody.password = params.password;
|
|
962
|
+
}
|
|
963
|
+
if (params.proxyUrl !== void 0) {
|
|
964
|
+
requestBody.proxy_url = params.proxyUrl;
|
|
965
|
+
}
|
|
966
|
+
if (params.remark !== void 0) {
|
|
967
|
+
requestBody.remark = params.remark;
|
|
968
|
+
}
|
|
969
|
+
if (params.ipchecker !== void 0) {
|
|
970
|
+
requestBody.ipchecker = params.ipchecker;
|
|
971
|
+
}
|
|
972
|
+
return requestBody;
|
|
973
|
+
}
|
|
974
|
+
function buildCreateProxyRequestBody(proxy) {
|
|
975
|
+
const requestBody = {};
|
|
976
|
+
requestBody.type = proxy.type;
|
|
977
|
+
requestBody.host = proxy.host;
|
|
978
|
+
requestBody.port = proxy.port;
|
|
979
|
+
if (proxy.user !== void 0) {
|
|
980
|
+
requestBody.user = proxy.user;
|
|
981
|
+
}
|
|
982
|
+
if (proxy.password !== void 0) {
|
|
983
|
+
requestBody.password = proxy.password;
|
|
984
|
+
}
|
|
985
|
+
if (proxy.proxy_url !== void 0) {
|
|
986
|
+
requestBody.proxy_url = proxy.proxy_url;
|
|
987
|
+
}
|
|
988
|
+
if (proxy.remark !== void 0) {
|
|
989
|
+
requestBody.remark = proxy.remark;
|
|
990
|
+
}
|
|
991
|
+
if (proxy.ipchecker !== void 0) {
|
|
992
|
+
requestBody.ipchecker = proxy.ipchecker;
|
|
993
|
+
}
|
|
994
|
+
return requestBody;
|
|
995
|
+
}
|
|
996
|
+
var proxyHandlers = {
|
|
997
|
+
async createProxy(params) {
|
|
998
|
+
const requestBody = params.proxies.map((proxy) => buildCreateProxyRequestBody(proxy));
|
|
999
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_PROXY}`, requestBody);
|
|
1000
|
+
if (response.data.code === 0) {
|
|
1001
|
+
return `Proxy created successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
1002
|
+
}
|
|
1003
|
+
throw new Error(`Failed to create proxy: ${response.data.msg}`);
|
|
1004
|
+
},
|
|
1005
|
+
async updateProxy(params) {
|
|
1006
|
+
const requestBody = buildProxyRequestBody(params);
|
|
1007
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PROXY}`, requestBody);
|
|
1008
|
+
if (response.data.code === 0) {
|
|
1009
|
+
return `Proxy updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
1010
|
+
}
|
|
1011
|
+
throw new Error(`Failed to update proxy: ${response.data.msg}`);
|
|
1012
|
+
},
|
|
1013
|
+
async getProxyList(params) {
|
|
1014
|
+
const { limit, page, proxyId } = params;
|
|
1015
|
+
const requestBody = {};
|
|
1016
|
+
if (limit !== void 0) {
|
|
1017
|
+
requestBody.limit = limit;
|
|
1018
|
+
}
|
|
1019
|
+
if (page !== void 0) {
|
|
1020
|
+
requestBody.page = page;
|
|
1021
|
+
}
|
|
1022
|
+
if (proxyId && proxyId.length > 0) {
|
|
1023
|
+
requestBody.proxy_id = proxyId;
|
|
1024
|
+
}
|
|
1025
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROXY_LIST}`, requestBody);
|
|
1026
|
+
if (response.data.code === 0) {
|
|
1027
|
+
return `Proxy list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
1028
|
+
}
|
|
1029
|
+
throw new Error(`Failed to get proxy list: ${response.data.msg}`);
|
|
1030
|
+
},
|
|
1031
|
+
async deleteProxy({ proxyIds }) {
|
|
1032
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_PROXY}`, {
|
|
1033
|
+
proxy_id: proxyIds
|
|
1034
|
+
});
|
|
1035
|
+
if (response.data.code === 0) {
|
|
1036
|
+
return `Proxies deleted successfully: ${proxyIds.join(", ")}`;
|
|
1037
|
+
}
|
|
1038
|
+
throw new Error(`Failed to delete proxies: ${response.data.msg}`);
|
|
1039
|
+
}
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
// ../core/src/handlers/tag.ts
|
|
1043
|
+
var tagHandlers = {
|
|
1044
|
+
async getTagList(params) {
|
|
1045
|
+
const { ids, limit, page } = params;
|
|
1046
|
+
const requestBody = {};
|
|
1047
|
+
if (ids && ids.length > 0) {
|
|
1048
|
+
requestBody.ids = ids;
|
|
1049
|
+
}
|
|
1050
|
+
if (limit !== void 0) {
|
|
1051
|
+
requestBody.limit = limit;
|
|
1052
|
+
}
|
|
1053
|
+
if (page !== void 0) {
|
|
1054
|
+
requestBody.page = page;
|
|
1055
|
+
}
|
|
1056
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_TAG_LIST}`, requestBody);
|
|
1057
|
+
if (response.data.code === 0) {
|
|
1058
|
+
return `Tag list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
1059
|
+
}
|
|
1060
|
+
throw new Error(`Failed to get tag list: ${response.data.msg}`);
|
|
1061
|
+
},
|
|
1062
|
+
async createTag({ tags }) {
|
|
1063
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_TAG}`, { tags });
|
|
1064
|
+
if (response.data.code === 0) {
|
|
1065
|
+
return `Tags created successfully: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
1066
|
+
}
|
|
1067
|
+
throw new Error(`Failed to create tags: ${response.data.msg}`);
|
|
1068
|
+
},
|
|
1069
|
+
async updateTag({ tags }) {
|
|
1070
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_TAG}`, { tags });
|
|
1071
|
+
if (response.data.code === 0) {
|
|
1072
|
+
return `Tags updated successfully: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
1073
|
+
}
|
|
1074
|
+
throw new Error(`Failed to update tags: ${response.data.msg}`);
|
|
1075
|
+
},
|
|
1076
|
+
async deleteTag({ ids }) {
|
|
1077
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_TAG}`, { ids });
|
|
1078
|
+
if (response.data.code === 0) {
|
|
1079
|
+
return `Tags deleted successfully: ${ids.join(", ")}`;
|
|
1080
|
+
}
|
|
1081
|
+
throw new Error(`Failed to delete tags: ${response.data.msg}`);
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
// ../core/src/handlers/automation.ts
|
|
1086
|
+
var import_path = __toESM(require("path"));
|
|
1087
|
+
var import_os = __toESM(require("os"));
|
|
1088
|
+
|
|
1089
|
+
// ../core/src/utils/browserBase.ts
|
|
1090
|
+
var import_playwright = require("playwright");
|
|
1091
|
+
var BrowserBase = class {
|
|
1092
|
+
browser;
|
|
1093
|
+
page;
|
|
1094
|
+
screenshots;
|
|
1095
|
+
constructor() {
|
|
1096
|
+
this.browser = null;
|
|
1097
|
+
this.page = null;
|
|
1098
|
+
this.screenshots = /* @__PURE__ */ new Map();
|
|
1099
|
+
}
|
|
1100
|
+
get browserInstance() {
|
|
1101
|
+
return this.browser;
|
|
1102
|
+
}
|
|
1103
|
+
get pageInstance() {
|
|
1104
|
+
return this.page;
|
|
1105
|
+
}
|
|
1106
|
+
set pageInstance(page) {
|
|
1107
|
+
this.page = page;
|
|
1108
|
+
}
|
|
1109
|
+
get screenshotsInstance() {
|
|
1110
|
+
return this.screenshots;
|
|
1111
|
+
}
|
|
1112
|
+
checkConnected() {
|
|
1113
|
+
const error = new Error("Browser not connected, please connect browser first");
|
|
1114
|
+
if (!this.browser) {
|
|
1115
|
+
throw error;
|
|
1116
|
+
}
|
|
1117
|
+
if (!this.browser.isConnected()) {
|
|
1118
|
+
throw error;
|
|
1119
|
+
}
|
|
1120
|
+
if (!this.page) {
|
|
1121
|
+
throw error;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
async connectBrowserWithWs(wsUrl) {
|
|
1125
|
+
this.browser = await import_playwright.chromium.connectOverCDP(wsUrl);
|
|
1126
|
+
const defaultContext = this.browser.contexts()[0];
|
|
1127
|
+
this.page = defaultContext.pages()[0];
|
|
1128
|
+
await this.page.bringToFront().catch((error) => {
|
|
1129
|
+
console.error("Failed to bring page to front", error);
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
async resetBrowser() {
|
|
1133
|
+
this.browser = null;
|
|
1134
|
+
this.page = null;
|
|
1135
|
+
}
|
|
1136
|
+
};
|
|
1137
|
+
var browserBase_default = new BrowserBase();
|
|
1138
|
+
|
|
1139
|
+
// ../core/src/handlers/automation.ts
|
|
1140
|
+
var defaultDownloadsPath = import_path.default.join(import_os.default.homedir(), "Downloads");
|
|
1141
|
+
|
|
1142
|
+
// ../core/src/handlers/kernel.ts
|
|
1143
|
+
var kernelHandlers = {
|
|
1144
|
+
async downloadKernel({ kernel_type, kernel_version }) {
|
|
1145
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DOWNLOAD_KERNEL}`, {
|
|
1146
|
+
kernel_type,
|
|
1147
|
+
kernel_version
|
|
1148
|
+
});
|
|
1149
|
+
if (response.data.code === 0) {
|
|
1150
|
+
return `Kernel download/update status: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
1151
|
+
}
|
|
1152
|
+
throw new Error(`Failed to download/update kernel: ${response.data.msg}`);
|
|
1153
|
+
},
|
|
1154
|
+
async getKernelList({ kernel_type }) {
|
|
1155
|
+
const params = new URLSearchParams();
|
|
1156
|
+
if (kernel_type) {
|
|
1157
|
+
params.set("kernel_type", kernel_type);
|
|
1158
|
+
}
|
|
1159
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_KERNEL_LIST}`, { params });
|
|
1160
|
+
if (response.data.code === 0) {
|
|
1161
|
+
return `Kernel list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
1162
|
+
}
|
|
1163
|
+
throw new Error(`Failed to get kernel list: ${response.data.msg}`);
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
|
|
1167
|
+
// ../core/src/handlers/patch.ts
|
|
1168
|
+
var patchHandlers = {
|
|
1169
|
+
async updatePatch({ version_type }) {
|
|
1170
|
+
const requestBody = {};
|
|
1171
|
+
if (version_type) {
|
|
1172
|
+
requestBody.version_type = version_type;
|
|
1173
|
+
}
|
|
1174
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PATCH}`, requestBody);
|
|
1175
|
+
if (response.data.code === 0) {
|
|
1176
|
+
return `Patch update status: ${JSON.stringify(response.data.data, null, 2)}, message: ${response.data.msg}`;
|
|
1177
|
+
}
|
|
1178
|
+
throw new Error(`Failed to update patch: ${response.data.msg}`);
|
|
1179
|
+
}
|
|
1180
|
+
};
|
|
1181
|
+
|
|
1182
|
+
// ../core/src/types/schemas.ts
|
|
1183
|
+
var import_zod = require("zod");
|
|
1184
|
+
var userProxyConfigSchema = import_zod.z.object({
|
|
1185
|
+
proxy_soft: import_zod.z.enum([
|
|
1186
|
+
"brightdata",
|
|
1187
|
+
"brightauto",
|
|
1188
|
+
"oxylabsauto",
|
|
1189
|
+
"922S5auto",
|
|
1190
|
+
"ipideeauto",
|
|
1191
|
+
"ipfoxyauto",
|
|
1192
|
+
"922S5auth",
|
|
1193
|
+
"kookauto",
|
|
1194
|
+
"ssh",
|
|
1195
|
+
"other",
|
|
1196
|
+
"no_proxy"
|
|
1197
|
+
]).describe("The proxy soft of the browser"),
|
|
1198
|
+
proxy_type: import_zod.z.enum(["http", "https", "socks5", "no_proxy"]).optional(),
|
|
1199
|
+
proxy_host: import_zod.z.string().optional().describe("The proxy host of the browser, eg: 127.0.0.1"),
|
|
1200
|
+
proxy_port: import_zod.z.string().optional().describe("The proxy port of the browser, eg: 8080"),
|
|
1201
|
+
proxy_user: import_zod.z.string().optional().describe("The proxy user of the browser, eg: user"),
|
|
1202
|
+
proxy_password: import_zod.z.string().optional().describe("The proxy password of the browser, eg: password"),
|
|
1203
|
+
proxy_url: import_zod.z.string().optional().describe("The proxy url of the browser, eg: http://127.0.0.1:8080"),
|
|
1204
|
+
global_config: import_zod.z.enum(["0", "1"]).optional().describe("The global config of the browser, default is 0")
|
|
1205
|
+
}).describe("The user proxy config of the browser");
|
|
1206
|
+
var CHROME_VERSIONS = [
|
|
1207
|
+
"92",
|
|
1208
|
+
"99",
|
|
1209
|
+
"102",
|
|
1210
|
+
"105",
|
|
1211
|
+
"108",
|
|
1212
|
+
"111",
|
|
1213
|
+
"114",
|
|
1214
|
+
"115",
|
|
1215
|
+
"116",
|
|
1216
|
+
"117",
|
|
1217
|
+
"118",
|
|
1218
|
+
"119",
|
|
1219
|
+
"120",
|
|
1220
|
+
"121",
|
|
1221
|
+
"122",
|
|
1222
|
+
"123",
|
|
1223
|
+
"124",
|
|
1224
|
+
"125",
|
|
1225
|
+
"126",
|
|
1226
|
+
"127",
|
|
1227
|
+
"128",
|
|
1228
|
+
"129",
|
|
1229
|
+
"130",
|
|
1230
|
+
"131",
|
|
1231
|
+
"132",
|
|
1232
|
+
"133",
|
|
1233
|
+
"134",
|
|
1234
|
+
"135",
|
|
1235
|
+
"136",
|
|
1236
|
+
"137",
|
|
1237
|
+
"138",
|
|
1238
|
+
"139",
|
|
1239
|
+
"140",
|
|
1240
|
+
"141",
|
|
1241
|
+
"142",
|
|
1242
|
+
"143",
|
|
1243
|
+
"144",
|
|
1244
|
+
"ua_auto"
|
|
1245
|
+
];
|
|
1246
|
+
var FIREFOX_VERSIONS = ["100", "107", "114", "120", "123", "126", "129", "132", "135", "138", "141", "144", "ua_auto"];
|
|
1247
|
+
var ALL_KERNEL_VERSIONS = [.../* @__PURE__ */ new Set([...CHROME_VERSIONS, ...FIREFOX_VERSIONS])];
|
|
1248
|
+
var browserKernelConfigSchema = import_zod.z.object({
|
|
1249
|
+
version: import_zod.z.union(
|
|
1250
|
+
ALL_KERNEL_VERSIONS.map((v) => import_zod.z.literal(v))
|
|
1251
|
+
).optional().describe("The version of the browser, must match type: chrome 92\u2013143 or ua_auto, firefox 100,107,114,120,123,126,129,132,135,138,141,144 or ua_auto; default is ua_auto"),
|
|
1252
|
+
type: import_zod.z.enum(["chrome", "firefox"]).optional().describe("The type of the browser, default is chrome")
|
|
1253
|
+
}).optional().superRefine((data, ctx) => {
|
|
1254
|
+
if (!data) return;
|
|
1255
|
+
const type = data.type ?? "chrome";
|
|
1256
|
+
const version = data.version;
|
|
1257
|
+
if (version === void 0) return;
|
|
1258
|
+
const validForChrome = CHROME_VERSIONS.includes(version);
|
|
1259
|
+
const validForFirefox = FIREFOX_VERSIONS.includes(version);
|
|
1260
|
+
if (type === "chrome" && !validForChrome) {
|
|
1261
|
+
ctx.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: `Chrome does not support version "${version}". Supported: ${CHROME_VERSIONS.join(", ")}` });
|
|
1262
|
+
}
|
|
1263
|
+
if (type === "firefox" && !validForFirefox) {
|
|
1264
|
+
ctx.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: `Firefox does not support version "${version}". Supported: ${FIREFOX_VERSIONS.join(", ")}` });
|
|
1265
|
+
}
|
|
1266
|
+
}).describe("The browser kernel config of the browser, default is version: ua_auto, type: chrome");
|
|
1267
|
+
var randomUaConfigSchema = import_zod.z.object({
|
|
1268
|
+
ua_version: import_zod.z.array(import_zod.z.string()).optional(),
|
|
1269
|
+
ua_system_version: import_zod.z.array(
|
|
1270
|
+
import_zod.z.enum([
|
|
1271
|
+
"Android 9",
|
|
1272
|
+
"Android 10",
|
|
1273
|
+
"Android 11",
|
|
1274
|
+
"Android 12",
|
|
1275
|
+
"Android 13",
|
|
1276
|
+
"Android 14",
|
|
1277
|
+
"Android 15",
|
|
1278
|
+
"iOS 14",
|
|
1279
|
+
"iOS 15",
|
|
1280
|
+
"iOS 16",
|
|
1281
|
+
"iOS 17",
|
|
1282
|
+
"iOS 18",
|
|
1283
|
+
"Windows 7",
|
|
1284
|
+
"Windows 8",
|
|
1285
|
+
"Windows 10",
|
|
1286
|
+
"Windows 11",
|
|
1287
|
+
"Mac OS X 10",
|
|
1288
|
+
"Mac OS X 11",
|
|
1289
|
+
"Mac OS X 12",
|
|
1290
|
+
"Mac OS X 13",
|
|
1291
|
+
"Mac OS X 14",
|
|
1292
|
+
"Mac OS X 15",
|
|
1293
|
+
"Mac OS X",
|
|
1294
|
+
"Windows",
|
|
1295
|
+
"iOS",
|
|
1296
|
+
"Android",
|
|
1297
|
+
"Linux"
|
|
1298
|
+
])
|
|
1299
|
+
).optional().describe(
|
|
1300
|
+
'UA system version. Mac OS X / Windows / iOS / Android / Linux = random any version of that system; omit to random across all systems. e.g. ["Android 9", "iOS 14"] or ["Android", "Mac OS X"]'
|
|
1301
|
+
)
|
|
1302
|
+
}).optional().describe("Random UA config (ua_version, ua_system_version). Ignored when fingerprint ua (custom UA) is set.");
|
|
1303
|
+
var TLS_CIPHER_SUITES = {
|
|
1304
|
+
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: "0xC02C",
|
|
1305
|
+
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: "0xC030",
|
|
1306
|
+
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "0xC02B",
|
|
1307
|
+
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: "0xC02F",
|
|
1308
|
+
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: "0xCCA9",
|
|
1309
|
+
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: "0xCCA8",
|
|
1310
|
+
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: "0x009F",
|
|
1311
|
+
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: "0x009E",
|
|
1312
|
+
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: "0xC024",
|
|
1313
|
+
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: "0xC028",
|
|
1314
|
+
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: "0xC00A",
|
|
1315
|
+
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: "0xC014",
|
|
1316
|
+
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: "0x006B",
|
|
1317
|
+
TLS_DHE_RSA_WITH_AES_256_CBC_SHA: "0x0039",
|
|
1318
|
+
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: "0xC023",
|
|
1319
|
+
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: "0xC027",
|
|
1320
|
+
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: "0xC009",
|
|
1321
|
+
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: "0xC013",
|
|
1322
|
+
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: "0x0067",
|
|
1323
|
+
TLS_DHE_RSA_WITH_AES_128_CBC_SHA: "0x0033",
|
|
1324
|
+
TLS_RSA_WITH_AES_256_GCM_SHA384: "0x009D",
|
|
1325
|
+
TLS_RSA_WITH_AES_128_GCM_SHA256: "0x009C",
|
|
1326
|
+
TLS_RSA_WITH_AES_256_CBC_SHA256: "0x003D",
|
|
1327
|
+
TLS_RSA_WITH_AES_128_CBC_SHA256: "0x003C",
|
|
1328
|
+
TLS_RSA_WITH_AES_256_CBC_SHA: "0x0035",
|
|
1329
|
+
TLS_RSA_WITH_AES_128_CBC_SHA: "0x002F",
|
|
1330
|
+
TLS_AES_128_CCM_8_SHA256: "0x1305",
|
|
1331
|
+
TLS_AES_128_CCM_SHA256: "0x1304"
|
|
1332
|
+
};
|
|
1333
|
+
var TLS_HEX_CODES = Object.values(TLS_CIPHER_SUITES);
|
|
1334
|
+
var COUNTRY_CODES = [
|
|
1335
|
+
"ad",
|
|
1336
|
+
"ae",
|
|
1337
|
+
"af",
|
|
1338
|
+
"ag",
|
|
1339
|
+
"ai",
|
|
1340
|
+
"al",
|
|
1341
|
+
"am",
|
|
1342
|
+
"ao",
|
|
1343
|
+
"aq",
|
|
1344
|
+
"ar",
|
|
1345
|
+
"as",
|
|
1346
|
+
"at",
|
|
1347
|
+
"au",
|
|
1348
|
+
"aw",
|
|
1349
|
+
"ax",
|
|
1350
|
+
"az",
|
|
1351
|
+
"ba",
|
|
1352
|
+
"bb",
|
|
1353
|
+
"bd",
|
|
1354
|
+
"be",
|
|
1355
|
+
"bf",
|
|
1356
|
+
"bg",
|
|
1357
|
+
"bh",
|
|
1358
|
+
"bi",
|
|
1359
|
+
"bj",
|
|
1360
|
+
"bl",
|
|
1361
|
+
"bm",
|
|
1362
|
+
"bn",
|
|
1363
|
+
"bo",
|
|
1364
|
+
"bq",
|
|
1365
|
+
"br",
|
|
1366
|
+
"bs",
|
|
1367
|
+
"bt",
|
|
1368
|
+
"bv",
|
|
1369
|
+
"bw",
|
|
1370
|
+
"by",
|
|
1371
|
+
"bz",
|
|
1372
|
+
"ca",
|
|
1373
|
+
"cc",
|
|
1374
|
+
"cd",
|
|
1375
|
+
"cf",
|
|
1376
|
+
"cg",
|
|
1377
|
+
"ch",
|
|
1378
|
+
"ci",
|
|
1379
|
+
"ck",
|
|
1380
|
+
"cl",
|
|
1381
|
+
"cm",
|
|
1382
|
+
"cn",
|
|
1383
|
+
"co",
|
|
1384
|
+
"cr",
|
|
1385
|
+
"cu",
|
|
1386
|
+
"cv",
|
|
1387
|
+
"cx",
|
|
1388
|
+
"cy",
|
|
1389
|
+
"cz",
|
|
1390
|
+
"de",
|
|
1391
|
+
"dj",
|
|
1392
|
+
"dk",
|
|
1393
|
+
"dm",
|
|
1394
|
+
"do",
|
|
1395
|
+
"dz",
|
|
1396
|
+
"ec",
|
|
1397
|
+
"ee",
|
|
1398
|
+
"eg",
|
|
1399
|
+
"eh",
|
|
1400
|
+
"er",
|
|
1401
|
+
"es",
|
|
1402
|
+
"et",
|
|
1403
|
+
"fi",
|
|
1404
|
+
"fj",
|
|
1405
|
+
"fk",
|
|
1406
|
+
"fm",
|
|
1407
|
+
"fo",
|
|
1408
|
+
"fr",
|
|
1409
|
+
"ga",
|
|
1410
|
+
"gb",
|
|
1411
|
+
"gd",
|
|
1412
|
+
"ge",
|
|
1413
|
+
"gf",
|
|
1414
|
+
"gg",
|
|
1415
|
+
"gh",
|
|
1416
|
+
"gi",
|
|
1417
|
+
"gl",
|
|
1418
|
+
"gm",
|
|
1419
|
+
"gn",
|
|
1420
|
+
"gp",
|
|
1421
|
+
"gq",
|
|
1422
|
+
"gr",
|
|
1423
|
+
"gs",
|
|
1424
|
+
"gt",
|
|
1425
|
+
"gu",
|
|
1426
|
+
"gw",
|
|
1427
|
+
"gy",
|
|
1428
|
+
"hk",
|
|
1429
|
+
"hm",
|
|
1430
|
+
"hn",
|
|
1431
|
+
"hr",
|
|
1432
|
+
"ht",
|
|
1433
|
+
"hu",
|
|
1434
|
+
"id",
|
|
1435
|
+
"ie",
|
|
1436
|
+
"il",
|
|
1437
|
+
"im",
|
|
1438
|
+
"in",
|
|
1439
|
+
"io",
|
|
1440
|
+
"iq",
|
|
1441
|
+
"ir",
|
|
1442
|
+
"is",
|
|
1443
|
+
"it",
|
|
1444
|
+
"je",
|
|
1445
|
+
"jm",
|
|
1446
|
+
"jo",
|
|
1447
|
+
"jp",
|
|
1448
|
+
"ke",
|
|
1449
|
+
"kg",
|
|
1450
|
+
"kh",
|
|
1451
|
+
"ki",
|
|
1452
|
+
"km",
|
|
1453
|
+
"kn",
|
|
1454
|
+
"kp",
|
|
1455
|
+
"kr",
|
|
1456
|
+
"kw",
|
|
1457
|
+
"ky",
|
|
1458
|
+
"kz",
|
|
1459
|
+
"la",
|
|
1460
|
+
"lb",
|
|
1461
|
+
"lc",
|
|
1462
|
+
"li",
|
|
1463
|
+
"lk",
|
|
1464
|
+
"lr",
|
|
1465
|
+
"ls",
|
|
1466
|
+
"lt",
|
|
1467
|
+
"lu",
|
|
1468
|
+
"lv",
|
|
1469
|
+
"ly",
|
|
1470
|
+
"ma",
|
|
1471
|
+
"mc",
|
|
1472
|
+
"md",
|
|
1473
|
+
"me",
|
|
1474
|
+
"mf",
|
|
1475
|
+
"mg",
|
|
1476
|
+
"mh",
|
|
1477
|
+
"mk",
|
|
1478
|
+
"ml",
|
|
1479
|
+
"mm",
|
|
1480
|
+
"mn",
|
|
1481
|
+
"mo",
|
|
1482
|
+
"mp",
|
|
1483
|
+
"mq",
|
|
1484
|
+
"mr",
|
|
1485
|
+
"ms",
|
|
1486
|
+
"mt",
|
|
1487
|
+
"mu",
|
|
1488
|
+
"mv",
|
|
1489
|
+
"mw",
|
|
1490
|
+
"mx",
|
|
1491
|
+
"my",
|
|
1492
|
+
"mz",
|
|
1493
|
+
"na",
|
|
1494
|
+
"nc",
|
|
1495
|
+
"ne",
|
|
1496
|
+
"nf",
|
|
1497
|
+
"ng",
|
|
1498
|
+
"ni",
|
|
1499
|
+
"nl",
|
|
1500
|
+
"no",
|
|
1501
|
+
"np",
|
|
1502
|
+
"nr",
|
|
1503
|
+
"nu",
|
|
1504
|
+
"nz",
|
|
1505
|
+
"om",
|
|
1506
|
+
"pa",
|
|
1507
|
+
"pe",
|
|
1508
|
+
"pf",
|
|
1509
|
+
"pg",
|
|
1510
|
+
"ph",
|
|
1511
|
+
"pk",
|
|
1512
|
+
"pl",
|
|
1513
|
+
"pm",
|
|
1514
|
+
"pn",
|
|
1515
|
+
"pr",
|
|
1516
|
+
"ps",
|
|
1517
|
+
"pt",
|
|
1518
|
+
"pw",
|
|
1519
|
+
"py",
|
|
1520
|
+
"qa",
|
|
1521
|
+
"re",
|
|
1522
|
+
"ro",
|
|
1523
|
+
"rs",
|
|
1524
|
+
"ru",
|
|
1525
|
+
"rw",
|
|
1526
|
+
"sa",
|
|
1527
|
+
"sb",
|
|
1528
|
+
"sc",
|
|
1529
|
+
"sd",
|
|
1530
|
+
"se",
|
|
1531
|
+
"sg",
|
|
1532
|
+
"sh",
|
|
1533
|
+
"si",
|
|
1534
|
+
"sj",
|
|
1535
|
+
"sk",
|
|
1536
|
+
"sl",
|
|
1537
|
+
"sm",
|
|
1538
|
+
"sn",
|
|
1539
|
+
"so",
|
|
1540
|
+
"sr",
|
|
1541
|
+
"ss",
|
|
1542
|
+
"st",
|
|
1543
|
+
"sv",
|
|
1544
|
+
"sy",
|
|
1545
|
+
"sz",
|
|
1546
|
+
"tc",
|
|
1547
|
+
"td",
|
|
1548
|
+
"tf",
|
|
1549
|
+
"tg",
|
|
1550
|
+
"th",
|
|
1551
|
+
"tj",
|
|
1552
|
+
"tk",
|
|
1553
|
+
"tl",
|
|
1554
|
+
"tm",
|
|
1555
|
+
"tn",
|
|
1556
|
+
"to",
|
|
1557
|
+
"tr",
|
|
1558
|
+
"tt",
|
|
1559
|
+
"tv",
|
|
1560
|
+
"tw",
|
|
1561
|
+
"tz",
|
|
1562
|
+
"ua",
|
|
1563
|
+
"ug",
|
|
1564
|
+
"um",
|
|
1565
|
+
"us",
|
|
1566
|
+
"uy",
|
|
1567
|
+
"uz",
|
|
1568
|
+
"va",
|
|
1569
|
+
"vc",
|
|
1570
|
+
"ve",
|
|
1571
|
+
"vg",
|
|
1572
|
+
"vi",
|
|
1573
|
+
"vn",
|
|
1574
|
+
"vu",
|
|
1575
|
+
"wf",
|
|
1576
|
+
"ws",
|
|
1577
|
+
"ye",
|
|
1578
|
+
"yt",
|
|
1579
|
+
"za",
|
|
1580
|
+
"zm",
|
|
1581
|
+
"zw"
|
|
1582
|
+
];
|
|
1583
|
+
var countryCodeSchema = import_zod.z.enum(COUNTRY_CODES);
|
|
1584
|
+
var webglConfigSchema = import_zod.z.object({
|
|
1585
|
+
unmasked_vendor: import_zod.z.string().describe('WebGL vendor string, e.g. "Google Inc.". Required when webgl=2, cannot be empty.'),
|
|
1586
|
+
unmasked_renderer: import_zod.z.string().describe('WebGL renderer string, e.g. "ANGLE (Intel(R) HD Graphics 620 Direct3D11 vs_5_0 ps_5_0)". Required when webgl=2, cannot be empty.'),
|
|
1587
|
+
webgpu: import_zod.z.object({
|
|
1588
|
+
webgpu_switch: import_zod.z.enum(["0", "1", "2"]).describe("0: Disabled, 1: WebGL based matching, 2: Real")
|
|
1589
|
+
}).optional().describe("WebGPU setting (V2.6.8.1+)")
|
|
1590
|
+
}).describe("Custom WebGL metadata when webgl=2. See AdsPower fingerprint_config webgl_config.");
|
|
1591
|
+
var macAddressConfigSchema = import_zod.z.object({
|
|
1592
|
+
model: import_zod.z.enum(["0", "1", "2"]).describe("0: use current computer MAC, 1: match appropriate value, 2: custom (address required)"),
|
|
1593
|
+
address: import_zod.z.string().optional().describe('Custom MAC address when model=2, e.g. "E4-02-9B-3B-E9-27"')
|
|
1594
|
+
}).describe("MAC address: model 0/1/2, address when model=2.");
|
|
1595
|
+
var DEVICE_COUNT_VALUES = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
1596
|
+
var mediaDevicesNumSchema = import_zod.z.object({
|
|
1597
|
+
audioinput_num: import_zod.z.enum(DEVICE_COUNT_VALUES).describe("Number of microphones, 1-9"),
|
|
1598
|
+
videoinput_num: import_zod.z.enum(DEVICE_COUNT_VALUES).describe("Number of cameras, 1-9"),
|
|
1599
|
+
audiooutput_num: import_zod.z.enum(DEVICE_COUNT_VALUES).describe("Number of speakers, 1-9")
|
|
1600
|
+
}).describe("Device counts when media_devices=2: audioinput_num, videoinput_num, audiooutput_num each 1-9.");
|
|
1601
|
+
var fingerprintConfigSchema = import_zod.z.object({
|
|
1602
|
+
automatic_timezone: import_zod.z.enum(["0", "1"]).optional().describe("Auto timezone by IP: 0 custom, 1 (default) by IP"),
|
|
1603
|
+
timezone: import_zod.z.string().optional().describe("Timezone when automatic_timezone=0, e.g. Asia/Shanghai"),
|
|
1604
|
+
location_switch: import_zod.z.enum(["0", "1"]).optional().describe("Location by IP: 0 custom, 1 (default) by IP"),
|
|
1605
|
+
longitude: import_zod.z.number().min(-180).max(180).optional().describe("Custom longitude when location_switch=0, -180 to 180, up to 6 decimals"),
|
|
1606
|
+
latitude: import_zod.z.number().min(-90).max(90).optional().describe("Custom latitude when location_switch=0, -90 to 90, up to 6 decimals"),
|
|
1607
|
+
accuracy: import_zod.z.number().int().min(10).max(5e3).optional().describe("Location accuracy in meters when location_switch=0, 10-5000, default 1000"),
|
|
1608
|
+
location: import_zod.z.enum(["ask", "allow", "block"]).optional().describe("Site location permission: ask (default), allow, block"),
|
|
1609
|
+
language_switch: import_zod.z.enum(["0", "1"]).optional().describe("Language by IP country: 0 custom, 1 (default) by IP"),
|
|
1610
|
+
language: import_zod.z.array(import_zod.z.string()).optional().describe('Custom languages when language_switch=0, e.g. ["en-US", "zh-CN"]'),
|
|
1611
|
+
page_language_switch: import_zod.z.enum(["0", "1"]).optional().describe("Match UI language to language: 0 off, 1 (default) on; Chrome 109+ Win / 119+ macOS, v2.6.72+"),
|
|
1612
|
+
page_language: import_zod.z.string().optional().describe("Page language when page_language_switch=0, e.g. en-US"),
|
|
1613
|
+
ua: import_zod.z.string().optional().describe("Custom User-Agent string; when set, takes precedence over random_ua (random_ua is not sent). Omit for random UA."),
|
|
1614
|
+
screen_resolution: import_zod.z.union([
|
|
1615
|
+
import_zod.z.enum(["none", "random"]),
|
|
1616
|
+
import_zod.z.string().regex(/^\d+_\d+$/, "Custom resolution format: width_height e.g. 1024_600")
|
|
1617
|
+
]).optional().describe("Screen resolution: none (default), random, or width_height e.g. 1024_600"),
|
|
1618
|
+
fonts: import_zod.z.array(import_zod.z.string()).optional().describe('Font list e.g. ["Arial", "Times New Roman"] or ["all"]'),
|
|
1619
|
+
canvas: import_zod.z.enum(["0", "1"]).optional().describe("Canvas fingerprint: 0 computer default, 1 (default) add noise"),
|
|
1620
|
+
webgl: import_zod.z.enum(["0", "2", "3"]).optional().describe("WebGL metadata: 0 computer default, 2 custom (use webgl_config), 3 random"),
|
|
1621
|
+
webgl_image: import_zod.z.enum(["0", "1"]).optional().describe("WebGL image fingerprint: 0 default, 1 (default) add noise"),
|
|
1622
|
+
webgl_config: webglConfigSchema.optional().describe("Custom WebGL metadata when webgl=2. Must include unmasked_vendor and unmasked_renderer (non-empty). webgpu.webgpu_switch: 0 Disabled, 1 WebGL based, 2 Real. V2.6.8.1+"),
|
|
1623
|
+
flash: import_zod.z.enum(["block", "allow"]).optional().describe("Flash: block (default) or allow"),
|
|
1624
|
+
webrtc: import_zod.z.enum(["disabled", "forward", "proxy", "local"]).optional().describe("WebRTC: disabled (default), forward, proxy, local"),
|
|
1625
|
+
audio: import_zod.z.enum(["0", "1"]).optional().describe("Audio fingerprint: 0 close, 1 (default) add noise"),
|
|
1626
|
+
do_not_track: import_zod.z.enum(["default", "true", "false"]).optional().describe("Do Not Track: default, true (open), false (close)"),
|
|
1627
|
+
hardware_concurrency: import_zod.z.enum(["2", "4", "6", "8", "16"]).optional().describe("CPU cores: 2, 4 (default if omitted), 6, 8, 16; omit to follow current computer"),
|
|
1628
|
+
device_memory: import_zod.z.enum(["2", "4", "6", "8"]).optional().describe("Device memory (GB): 2, 4, 6, 8 (default if omitted); omit to follow current computer"),
|
|
1629
|
+
scan_port_type: import_zod.z.enum(["0", "1"]).optional().describe("Port scan protection: 0 close, 1 (default) enable"),
|
|
1630
|
+
allow_scan_ports: import_zod.z.array(import_zod.z.string()).optional().describe('Ports allowed when scan_port_type=1, e.g. ["4000","4001"]. Empty to not pass.'),
|
|
1631
|
+
media_devices: import_zod.z.enum(["0", "1", "2"]).optional().describe("Media devices: 0 off (use computer default), 1 noise (count follows local), 2 noise (use media_devices_num). V2.6.4.2+"),
|
|
1632
|
+
media_devices_num: mediaDevicesNumSchema.optional().describe("When media_devices=2: audioinput_num, videoinput_num, audiooutput_num each 1-9. V2.6.4.2+"),
|
|
1633
|
+
client_rects: import_zod.z.enum(["0", "1"]).optional().describe("ClientRects: 0 use computer default, 1 add noise. V3.6.2+"),
|
|
1634
|
+
device_name_switch: import_zod.z.enum(["0", "1", "2"]).optional().describe("Device name: 0 close (use computer name), 1 mask, 2 custom (use device_name). V3.6.25+"),
|
|
1635
|
+
device_name: import_zod.z.string().optional().describe("Custom device name when device_name_switch=2. V2.4.8.1+"),
|
|
1636
|
+
speech_switch: import_zod.z.enum(["0", "1"]).optional().describe("SpeechVoices: 0 use computer default, 1 replace with value. V3.11.10+"),
|
|
1637
|
+
mac_address_config: macAddressConfigSchema.optional().describe("MAC address: model 0/1/2, address when model=2. V4.3.9+"),
|
|
1638
|
+
gpu: import_zod.z.enum(["0", "1", "2"]).optional().describe("GPU: 0 follow Local settings - Hardware acceleration, 1 turn on, 2 turn off"),
|
|
1639
|
+
browser_kernel_config: browserKernelConfigSchema.optional(),
|
|
1640
|
+
random_ua: randomUaConfigSchema.optional().describe("Random UA config; ignored when ua (custom UA) is provided."),
|
|
1641
|
+
tls_switch: import_zod.z.enum(["0", "1"]).optional().describe("TLS custom list: 0 (default) off, 1 on"),
|
|
1642
|
+
tls: import_zod.z.string().optional().refine(
|
|
1643
|
+
(val) => !val || val.split(",").every((hex) => TLS_HEX_CODES.includes(hex.trim())),
|
|
1644
|
+
{ message: `tls must be comma-separated hex codes from: ${TLS_HEX_CODES.join(", ")}. e.g. "0xC02C,0xC030"` }
|
|
1645
|
+
).describe("TLS cipher list when tls_switch=1: comma-separated hex codes. Chrome kernel only.")
|
|
1646
|
+
}).optional().superRefine((data, ctx) => {
|
|
1647
|
+
if (!data) return;
|
|
1648
|
+
if (data.browser_kernel_config?.type === "firefox" && data.tls) {
|
|
1649
|
+
ctx.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "tls is only supported for Chrome kernel", path: ["tls"] });
|
|
1650
|
+
}
|
|
1651
|
+
if (data.webgl === "2") {
|
|
1652
|
+
const wc = data.webgl_config;
|
|
1653
|
+
if (!wc || typeof wc.unmasked_vendor !== "string" || wc.unmasked_vendor.trim() === "") {
|
|
1654
|
+
ctx.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "When webgl=2, webgl_config.unmasked_vendor is required and cannot be empty", path: ["webgl_config", "unmasked_vendor"] });
|
|
1655
|
+
}
|
|
1656
|
+
if (!wc || typeof wc.unmasked_renderer !== "string" || wc.unmasked_renderer.trim() === "") {
|
|
1657
|
+
ctx.addIssue({ code: import_zod.z.ZodIssueCode.custom, message: "When webgl=2, webgl_config.unmasked_renderer is required and cannot be empty", path: ["webgl_config", "unmasked_renderer"] });
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
}).describe("Fingerprint config (fingerprint_config). All fields optional. See AdsPower Local API fingerprint_config.");
|
|
1661
|
+
var schemas = {
|
|
1662
|
+
createBrowserSchema: import_zod.z.object({
|
|
1663
|
+
groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group, use 0 for Ungrouped'),
|
|
1664
|
+
username: import_zod.z.string().optional().describe("Platform account username"),
|
|
1665
|
+
password: import_zod.z.string().optional().describe("Platform account password"),
|
|
1666
|
+
cookie: import_zod.z.string().optional().describe("Cookie data in JSON or Netscape format"),
|
|
1667
|
+
fakey: import_zod.z.string().optional().describe("2FA key for online 2FA code generators"),
|
|
1668
|
+
name: import_zod.z.string().max(100).optional().describe("Account name, max 100 characters"),
|
|
1669
|
+
platform: import_zod.z.string().optional().describe("Platform domain, eg: facebook.com"),
|
|
1670
|
+
remark: import_zod.z.string().optional().describe("Remarks to describe the account. Maximum 1500 characters."),
|
|
1671
|
+
userProxyConfig: userProxyConfigSchema.default({ proxy_soft: "no_proxy" }).describe("Proxy configuration. If proxyid is provided, proxyid takes priority and this field is ignored. Defaults to no_proxy when neither proxyid nor a custom proxy is needed."),
|
|
1672
|
+
proxyid: import_zod.z.string().optional().describe("Proxy profile ID. Takes priority over userProxyConfig when provided."),
|
|
1673
|
+
repeatConfig: import_zod.z.array(import_zod.z.union([import_zod.z.literal(0), import_zod.z.literal(2), import_zod.z.literal(3), import_zod.z.literal(4)])).optional().describe("Account deduplication settings (0, 2, 3, or 4)"),
|
|
1674
|
+
ignoreCookieError: import_zod.z.enum(["0", "1"]).optional().describe("Handle cookie verification failures: 0 (default) return data as-is, 1 filter out incorrectly formatted cookies"),
|
|
1675
|
+
tabs: import_zod.z.array(import_zod.z.string()).optional().describe('URLs to open on startup, eg: ["https://www.google.com"]'),
|
|
1676
|
+
ip: import_zod.z.string().optional().describe("IP address"),
|
|
1677
|
+
country: countryCodeSchema.optional().describe('Country/Region, ISO 3166-1 alpha-2 (lowercase). eg: "cn", "us"'),
|
|
1678
|
+
region: import_zod.z.string().optional().describe("Region"),
|
|
1679
|
+
city: import_zod.z.string().optional().describe("City"),
|
|
1680
|
+
ipchecker: import_zod.z.enum(["ip2location", "ipapi"]).optional().describe("IP query channel"),
|
|
1681
|
+
categoryId: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
|
|
1682
|
+
profileTagIds: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to assign to the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
|
|
1683
|
+
fingerprintConfig: fingerprintConfigSchema.optional().default({ random_ua: { ua_system_version: ["Windows"] } })
|
|
1684
|
+
}),
|
|
1685
|
+
updateBrowserSchema: import_zod.z.object({
|
|
1686
|
+
platform: import_zod.z.string().optional().describe("The platform of the browser, eg: facebook.com"),
|
|
1687
|
+
tabs: import_zod.z.array(import_zod.z.string()).optional().describe('The tabs of the browser, eg: ["https://www.google.com"]'),
|
|
1688
|
+
cookie: import_zod.z.string().optional().describe("The cookie of the browser"),
|
|
1689
|
+
username: import_zod.z.string().optional().describe('The username of the browser, eg: "user"'),
|
|
1690
|
+
password: import_zod.z.string().optional().describe('The password of the browser, eg: "password"'),
|
|
1691
|
+
fakey: import_zod.z.string().optional().describe("Enter the 2FA-key"),
|
|
1692
|
+
ignoreCookieError: import_zod.z.enum(["0", "1"]).optional().describe("Specifies how to handle the case when cookie validation fails."),
|
|
1693
|
+
groupId: import_zod.z.string().optional().describe('The group id of the browser, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list or create a new group'),
|
|
1694
|
+
name: import_zod.z.string().max(100).optional().describe('The Profile name of the browser, eg: "My Browser"'),
|
|
1695
|
+
remark: import_zod.z.string().max(1500).optional().describe("Profile remarks, maximum 1500 characters"),
|
|
1696
|
+
country: countryCodeSchema.optional().describe('The country of the browser, ISO 3166-1 alpha-2 (lowercase). eg: "cn", "us"'),
|
|
1697
|
+
region: import_zod.z.string().optional().describe("The region of the browser"),
|
|
1698
|
+
city: import_zod.z.string().optional().describe("The city of the browser"),
|
|
1699
|
+
ip: import_zod.z.string().optional().describe("The IP of the browser"),
|
|
1700
|
+
categoryId: import_zod.z.string().optional().describe("The category id of the browser, you can use the get-application-list tool to get the application list"),
|
|
1701
|
+
userProxyConfig: userProxyConfigSchema.optional(),
|
|
1702
|
+
proxyid: import_zod.z.string().optional().describe("Proxy ID"),
|
|
1703
|
+
fingerprintConfig: fingerprintConfigSchema.optional(),
|
|
1704
|
+
launchArgs: import_zod.z.string().optional().describe("Browser startup parameters"),
|
|
1705
|
+
profileTagIds: import_zod.z.array(import_zod.z.string()).max(30).optional().describe('Tag IDs to set on the profile, max 30 tags per profile. Example: ["tag1","tag2"]'),
|
|
1706
|
+
tagsUpdateType: import_zod.z.enum(["1", "2"]).optional().describe('How to apply profile_tag_ids: "1" (default) replace all existing tags; "2" append tags (truncated to 30 total if exceeded)'),
|
|
1707
|
+
profileId: import_zod.z.string().describe("The profile id of the browser to update, it is required when you want to update the browser")
|
|
1708
|
+
}),
|
|
1709
|
+
openBrowserSchema: import_zod.z.object({
|
|
1710
|
+
profileNo: import_zod.z.string().optional().describe("Priority will be given to user id when profile_id is filled."),
|
|
1711
|
+
profileId: import_zod.z.string().describe("Unique profile ID, generated after creating profile. The profile id of the browser to open"),
|
|
1712
|
+
ipTab: import_zod.z.enum(["0", "1"]).optional().describe("The ip tab of the browser, 0 is not use ip tab, 1 is use ip tab, default is 0"),
|
|
1713
|
+
launchArgs: import_zod.z.string().optional().describe("The launch args of the browser, use chrome launch args, or vista url"),
|
|
1714
|
+
clearCacheAfterClosing: import_zod.z.enum(["0", "1"]).optional().describe("The clear cache after closing of the browser, 0 is not clear cache after closing, 1 is clear cache after closing, default is 0"),
|
|
1715
|
+
cdpMask: import_zod.z.enum(["0", "1"]).optional().describe("The cdp mask of the browser, 0 is not use cdp mask, 1 is use cdp mask, default is 0")
|
|
1716
|
+
}).strict(),
|
|
1717
|
+
closeBrowserSchema: import_zod.z.object({
|
|
1718
|
+
profileId: import_zod.z.string().optional().describe("The profile id of the browser to stop, either profileId or profileNo must be provided"),
|
|
1719
|
+
profileNo: import_zod.z.string().optional().describe("The profile number of the browser to stop, priority will be given to profileId when profileId is filled")
|
|
1720
|
+
}).refine((data) => data.profileId || data.profileNo, {
|
|
1721
|
+
message: "Either profileId or profileNo must be provided"
|
|
1722
|
+
}),
|
|
1723
|
+
deleteBrowserSchema: import_zod.z.object({
|
|
1724
|
+
profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids of the browsers to delete, it is required when you want to delete the browser")
|
|
1725
|
+
}).strict(),
|
|
1726
|
+
getBrowserListSchema: import_zod.z.object({
|
|
1727
|
+
groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").optional().describe("Query by group ID; searches all groups if empty"),
|
|
1728
|
+
limit: import_zod.z.number().optional().describe("Profiles per page. Number of profiles returned per page, range 1 ~ 200, default is 50"),
|
|
1729
|
+
page: import_zod.z.number().optional().describe("Page number for results, default is 1"),
|
|
1730
|
+
profileId: import_zod.z.array(import_zod.z.string()).optional().describe('Query by profile ID. Example: ["h1yynkm","h1yynks"]'),
|
|
1731
|
+
profileNo: import_zod.z.array(import_zod.z.string()).optional().describe('Query by profile number. Example: ["123","124"]'),
|
|
1732
|
+
sortType: import_zod.z.enum(["profile_no", "last_open_time", "created_time"]).optional().describe("Sort results by: profile_no, last_open_time, or created_time"),
|
|
1733
|
+
sortOrder: import_zod.z.enum(["asc", "desc"]).optional().describe('Sort order: "asc" (ascending) or "desc" (descending)'),
|
|
1734
|
+
tag_ids: import_zod.z.array(import_zod.z.string()).optional().describe('Tag IDs to filter profiles by tags. Example: ["tag1","tag2"]'),
|
|
1735
|
+
tags_filter: import_zod.z.enum(["include", "exclude"]).optional().describe('Tag matching mode: "include" (default) matches profiles with any of the tags, "exclude" matches profiles without the tags'),
|
|
1736
|
+
name: import_zod.z.string().optional().describe("Profile name keyword to search for"),
|
|
1737
|
+
name_filter: import_zod.z.enum(["include", "exclude"]).optional().describe('Name matching mode: "include" (default) matches profiles containing the name keyword, "exclude" matches profiles not containing the name keyword')
|
|
1738
|
+
}).strict(),
|
|
1739
|
+
moveBrowserSchema: import_zod.z.object({
|
|
1740
|
+
groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The target group id, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
|
|
1741
|
+
userIds: import_zod.z.array(import_zod.z.string()).describe("The browser Profile ids to move")
|
|
1742
|
+
}).strict(),
|
|
1743
|
+
getProfileCookiesSchema: import_zod.z.object({
|
|
1744
|
+
profileId: import_zod.z.string().optional().describe("The profile id, either profileId or profileNo must be provided"),
|
|
1745
|
+
profileNo: import_zod.z.string().optional().describe("The profile number, priority will be given to profileId when profileId is filled")
|
|
1746
|
+
}).refine((data) => data.profileId || data.profileNo, {
|
|
1747
|
+
message: "Either profileId or profileNo must be provided"
|
|
1748
|
+
}),
|
|
1749
|
+
getProfileUaSchema: import_zod.z.object({
|
|
1750
|
+
profileId: import_zod.z.array(import_zod.z.string()).optional().describe("The profile id array, either profileId or profileNo must be provided"),
|
|
1751
|
+
profileNo: import_zod.z.array(import_zod.z.string()).optional().describe("The profile number array, priority will be given to profileId when profileId is filled")
|
|
1752
|
+
}).refine((data) => data.profileId && data.profileId.length > 0 || data.profileNo && data.profileNo.length > 0, {
|
|
1753
|
+
message: "Either profileId or profileNo must be provided with at least one element"
|
|
1754
|
+
}),
|
|
1755
|
+
closeAllProfilesSchema: import_zod.z.object({}).strict(),
|
|
1756
|
+
newFingerprintSchema: import_zod.z.object({
|
|
1757
|
+
profileId: import_zod.z.array(import_zod.z.string()).optional().describe("The profile id array, either profileId or profileNo must be provided"),
|
|
1758
|
+
profileNo: import_zod.z.array(import_zod.z.string()).optional().describe("The profile number array, priority will be given to profileId when profileId is filled")
|
|
1759
|
+
}).strict(),
|
|
1760
|
+
deleteCacheV2Schema: import_zod.z.object({
|
|
1761
|
+
profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
|
|
1762
|
+
type: import_zod.z.array(import_zod.z.enum(["local_storage", "indexeddb", "extension_cache", "cookie", "history", "image_file"])).describe("Types of cache to clear, it is required")
|
|
1763
|
+
}).strict(),
|
|
1764
|
+
shareProfileSchema: import_zod.z.object({
|
|
1765
|
+
profileIds: import_zod.z.array(import_zod.z.string()).describe("The profile ids array, it is required"),
|
|
1766
|
+
receiver: import_zod.z.string().describe("Receiver's account email or phone number (no area code), it is required"),
|
|
1767
|
+
shareType: import_zod.z.number().int().optional().describe("Share type: 1 for email (default), 2 for phone number"),
|
|
1768
|
+
content: import_zod.z.array(import_zod.z.enum(["name", "proxy", "remark", "tabs"])).optional().describe("Shared content")
|
|
1769
|
+
}).strict(),
|
|
1770
|
+
createGroupSchema: import_zod.z.object({
|
|
1771
|
+
groupName: import_zod.z.string().describe("The name of the group to create"),
|
|
1772
|
+
remark: import_zod.z.string().optional().describe("The remark of the group")
|
|
1773
|
+
}).strict(),
|
|
1774
|
+
updateGroupSchema: import_zod.z.object({
|
|
1775
|
+
groupId: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").describe('The id of the group to update, must be a numeric string (e.g., "123"). You can use the get-group-list tool to get the group list'),
|
|
1776
|
+
groupName: import_zod.z.string().describe("The new name of the group"),
|
|
1777
|
+
remark: import_zod.z.string().nullable().optional().describe("The new remark of the group")
|
|
1778
|
+
}).strict(),
|
|
1779
|
+
getGroupListSchema: import_zod.z.object({
|
|
1780
|
+
groupName: import_zod.z.string().optional().describe("The name of the group to search, use like to search"),
|
|
1781
|
+
size: import_zod.z.number().optional().describe("The size of the page, max is 100, default is 10"),
|
|
1782
|
+
page: import_zod.z.number().optional().describe("The page of the group, default is 1")
|
|
1783
|
+
}).strict(),
|
|
1784
|
+
getApplicationListSchema: import_zod.z.object({
|
|
1785
|
+
category_id: import_zod.z.string().optional().describe("Extension category_id"),
|
|
1786
|
+
page: import_zod.z.number().optional().describe("Page number, default 1"),
|
|
1787
|
+
limit: import_zod.z.number().min(1).max(100).optional().describe("Default 1, how many values are returned per page, range 1 to 100")
|
|
1788
|
+
}).strict(),
|
|
1789
|
+
getBrowserActiveSchema: import_zod.z.object({
|
|
1790
|
+
profileId: import_zod.z.string().optional().describe("The profile id, either profileId or profileNo must be provided"),
|
|
1791
|
+
profileNo: import_zod.z.string().optional().describe("The profile number, priority will be given to profileId when profileId is filled")
|
|
1792
|
+
}).refine((data) => data.profileId || data.profileNo, {
|
|
1793
|
+
message: "Either profileId or profileNo must be provided"
|
|
1794
|
+
}),
|
|
1795
|
+
getCloudActiveSchema: import_zod.z.object({
|
|
1796
|
+
userIds: import_zod.z.string().describe("Profile IDs string to check (split by comma, max 100 per request). Unique profile ID, generated after creating the profile.")
|
|
1797
|
+
}).refine((data) => data.userIds.split(",").length <= 100, {
|
|
1798
|
+
message: "The number of profile ids is too many, the maximum is 100"
|
|
1799
|
+
}),
|
|
1800
|
+
createProxySchema: import_zod.z.object({
|
|
1801
|
+
proxies: import_zod.z.array(import_zod.z.object({
|
|
1802
|
+
type: import_zod.z.enum(["http", "https", "ssh", "socks5"]).describe("Proxy type, support: http/https/ssh/socks5"),
|
|
1803
|
+
host: import_zod.z.string().describe("Proxy host, support: ipV4, ipV6, eg: 192.168.0.1"),
|
|
1804
|
+
port: import_zod.z.string().describe("Port, range: 0-65536, eg: 8000"),
|
|
1805
|
+
user: import_zod.z.string().optional().describe("Proxy username, eg: user12345678"),
|
|
1806
|
+
password: import_zod.z.string().optional().describe("Proxy password, eg: password"),
|
|
1807
|
+
proxy_url: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
|
|
1808
|
+
remark: import_zod.z.string().optional().describe("Remark/description for the proxy"),
|
|
1809
|
+
ipchecker: import_zod.z.enum(["ipinfo", "ip2location", "ipapi", "ipfoxy"]).optional().describe("IP checker.")
|
|
1810
|
+
}).strict()).describe("Array of proxy configurations to create")
|
|
1811
|
+
}).strict(),
|
|
1812
|
+
updateProxySchema: import_zod.z.object({
|
|
1813
|
+
proxyId: import_zod.z.string().describe("The unique id after the proxy is added"),
|
|
1814
|
+
type: import_zod.z.enum(["http", "https", "ssh", "socks5"]).optional().describe("Proxy type, support: http/https/ssh/socks5"),
|
|
1815
|
+
host: import_zod.z.string().optional().describe("Proxy host, support: ipV4, ipV6, eg: 192.168.0.1"),
|
|
1816
|
+
port: import_zod.z.string().optional().describe("Port, range: 0-65536, eg: 8000"),
|
|
1817
|
+
user: import_zod.z.string().optional().describe("Proxy username, eg: user12345678"),
|
|
1818
|
+
password: import_zod.z.string().optional().describe("Proxy password, eg: password"),
|
|
1819
|
+
proxyUrl: import_zod.z.string().optional().describe("URL used to refresh the proxy, eg: https://www.baidu.com/"),
|
|
1820
|
+
remark: import_zod.z.string().optional().describe("Remark/description for the proxy"),
|
|
1821
|
+
ipchecker: import_zod.z.enum(["ip2location", "ipapi", "ipfoxy"]).optional().describe("IP checker.")
|
|
1822
|
+
}).strict(),
|
|
1823
|
+
getProxyListSchema: import_zod.z.object({
|
|
1824
|
+
limit: import_zod.z.number().optional().describe("Profiles per page. Number of proxies returned per page, range 1 ~ 200, default is 50"),
|
|
1825
|
+
page: import_zod.z.number().optional().describe("Page number for results, default is 1"),
|
|
1826
|
+
proxyId: import_zod.z.array(import_zod.z.string()).optional().describe('Query by proxy ID. Example: ["proxy1","proxy2"]')
|
|
1827
|
+
}).strict(),
|
|
1828
|
+
deleteProxySchema: import_zod.z.object({
|
|
1829
|
+
proxyIds: import_zod.z.array(import_zod.z.string()).describe("The proxy ids of the proxies to delete, it is required when you want to delete the proxy. The maximum is 100. ")
|
|
1830
|
+
}).strict(),
|
|
1831
|
+
getTagListSchema: import_zod.z.object({
|
|
1832
|
+
ids: import_zod.z.array(import_zod.z.string()).optional().describe('Tag IDs to query, max 100 per request. Example: ["tag1","tag2"]'),
|
|
1833
|
+
limit: import_zod.z.number().optional().describe("Number of tags returned per page, range 1 ~ 200, default is 50"),
|
|
1834
|
+
page: import_zod.z.number().optional().describe("Page number for results, default is 1")
|
|
1835
|
+
}).strict(),
|
|
1836
|
+
createTagSchema: import_zod.z.object({
|
|
1837
|
+
tags: import_zod.z.array(import_zod.z.object({
|
|
1838
|
+
name: import_zod.z.string().max(50).describe("Tag name, max 50 characters"),
|
|
1839
|
+
color: import_zod.z.enum(["darkBlue", "blue", "purple", "red", "yellow", "orange", "green", "lightGreen"]).optional().describe("Tag color, default is darkBlue")
|
|
1840
|
+
}).strict()).describe("Array of tags to create")
|
|
1841
|
+
}).strict(),
|
|
1842
|
+
updateTagSchema: import_zod.z.object({
|
|
1843
|
+
tags: import_zod.z.array(import_zod.z.object({
|
|
1844
|
+
id: import_zod.z.string().describe("Tag ID to update"),
|
|
1845
|
+
name: import_zod.z.string().max(50).optional().describe("Tag name, max 50 characters"),
|
|
1846
|
+
color: import_zod.z.enum(["darkBlue", "blue", "purple", "red", "yellow", "orange", "green", "lightGreen"]).optional().describe("Tag color")
|
|
1847
|
+
}).strict()).describe("Array of tags to update")
|
|
1848
|
+
}).strict(),
|
|
1849
|
+
deleteTagSchema: import_zod.z.object({
|
|
1850
|
+
ids: import_zod.z.array(import_zod.z.string()).describe("Tag IDs to delete")
|
|
1851
|
+
}).strict(),
|
|
1852
|
+
downloadKernelSchema: import_zod.z.object({
|
|
1853
|
+
kernel_type: import_zod.z.enum(["Chrome", "Firefox"]).describe("Browser kernel type"),
|
|
1854
|
+
kernel_version: import_zod.z.string().describe("Browser kernel version, e.g. 141")
|
|
1855
|
+
}).strict(),
|
|
1856
|
+
getKernelListSchema: import_zod.z.object({
|
|
1857
|
+
kernel_type: import_zod.z.enum(["Chrome", "Firefox"]).optional().describe("Browser kernel type; omit to return all supported kernels")
|
|
1858
|
+
}).strict(),
|
|
1859
|
+
updatePatchSchema: import_zod.z.object({
|
|
1860
|
+
version_type: import_zod.z.enum(["stable", "beta"]).optional().describe("Patch version type to update, default stable")
|
|
1861
|
+
}).strict(),
|
|
1862
|
+
emptySchema: import_zod.z.object({}).strict(),
|
|
1863
|
+
createAutomationSchema: import_zod.z.object({
|
|
1864
|
+
userId: import_zod.z.string().optional().describe("The browser id of the browser to connect"),
|
|
1865
|
+
serialNumber: import_zod.z.string().optional().describe("The serial number of the browser to connect"),
|
|
1866
|
+
wsUrl: import_zod.z.string().describe("The ws url of the browser, get from the open-browser tool content `ws.puppeteer`")
|
|
1867
|
+
}).strict(),
|
|
1868
|
+
navigateSchema: import_zod.z.object({
|
|
1869
|
+
url: import_zod.z.string().describe("The url to navigate to")
|
|
1870
|
+
}).strict(),
|
|
1871
|
+
screenshotSchema: import_zod.z.object({
|
|
1872
|
+
savePath: import_zod.z.string().optional().describe("The path to save the screenshot"),
|
|
1873
|
+
isFullPage: import_zod.z.boolean().optional().describe("The is full page of the screenshot")
|
|
1874
|
+
}).strict(),
|
|
1875
|
+
clickElementSchema: import_zod.z.object({
|
|
1876
|
+
selector: import_zod.z.string().describe("The selector of the element to click, find from the page source code")
|
|
1877
|
+
}).strict(),
|
|
1878
|
+
fillInputSchema: import_zod.z.object({
|
|
1879
|
+
selector: import_zod.z.string().describe("The selector of the input to fill, find from the page source code"),
|
|
1880
|
+
text: import_zod.z.string().describe("The text to fill in the input")
|
|
1881
|
+
}).strict(),
|
|
1882
|
+
selectOptionSchema: import_zod.z.object({
|
|
1883
|
+
selector: import_zod.z.string().describe("The selector of the option to select, find from the page source code"),
|
|
1884
|
+
value: import_zod.z.string().describe("The value of the option to select")
|
|
1885
|
+
}).strict(),
|
|
1886
|
+
hoverElementSchema: import_zod.z.object({
|
|
1887
|
+
selector: import_zod.z.string().describe("The selector of the element to hover, find from the page source code")
|
|
1888
|
+
}).strict(),
|
|
1889
|
+
scrollElementSchema: import_zod.z.object({
|
|
1890
|
+
selector: import_zod.z.string().describe("The selector of the element to scroll, find from the page source code")
|
|
1891
|
+
}).strict(),
|
|
1892
|
+
pressKeySchema: import_zod.z.object({
|
|
1893
|
+
key: import_zod.z.string().describe('The key to press, eg: "Enter"'),
|
|
1894
|
+
selector: import_zod.z.string().optional().describe("The selector of the element to press the key, find from the page source code")
|
|
1895
|
+
}).strict(),
|
|
1896
|
+
evaluateScriptSchema: import_zod.z.object({
|
|
1897
|
+
script: import_zod.z.string().describe(`The script to evaluate, eg: "document.querySelector('#username').value = 'test'"`)
|
|
1898
|
+
}).strict(),
|
|
1899
|
+
dragElementSchema: import_zod.z.object({
|
|
1900
|
+
selector: import_zod.z.string().describe("The selector of the element to drag, find from the page source code"),
|
|
1901
|
+
targetSelector: import_zod.z.string().describe("The selector of the element to drag to, find from the page source code")
|
|
1902
|
+
}).strict(),
|
|
1903
|
+
iframeClickElementSchema: import_zod.z.object({
|
|
1904
|
+
selector: import_zod.z.string().describe("The selector of the element to click, find from the page source code"),
|
|
1905
|
+
iframeSelector: import_zod.z.string().describe("The selector of the iframe to click, find from the page source code")
|
|
1906
|
+
}).strict()
|
|
1907
|
+
};
|
|
1908
|
+
|
|
1909
|
+
// src/cli.ts
|
|
1910
|
+
var STATELESS_HANDLERS = {
|
|
1911
|
+
"open-browser": {
|
|
1912
|
+
fn: browserHandlers.openBrowser,
|
|
1913
|
+
description: "Open the browser, both environment and profile mean browser"
|
|
1914
|
+
},
|
|
1915
|
+
"close-browser": {
|
|
1916
|
+
fn: browserHandlers.closeBrowser,
|
|
1917
|
+
description: "Close the browser"
|
|
1918
|
+
},
|
|
1919
|
+
"create-browser": {
|
|
1920
|
+
fn: browserHandlers.createBrowser,
|
|
1921
|
+
description: "Create a browser"
|
|
1922
|
+
},
|
|
1923
|
+
"update-browser": {
|
|
1924
|
+
fn: browserHandlers.updateBrowser,
|
|
1925
|
+
description: "Update the browser"
|
|
1926
|
+
},
|
|
1927
|
+
"delete-browser": {
|
|
1928
|
+
fn: browserHandlers.deleteBrowser,
|
|
1929
|
+
description: "Delete the browser"
|
|
1930
|
+
},
|
|
1931
|
+
"get-browser-list": {
|
|
1932
|
+
fn: browserHandlers.getBrowserList,
|
|
1933
|
+
description: "Get the list of browsers"
|
|
1934
|
+
},
|
|
1935
|
+
"get-opened-browser": {
|
|
1936
|
+
fn: browserHandlers.getOpenedBrowser,
|
|
1937
|
+
description: "Get the list of opened browsers"
|
|
1938
|
+
},
|
|
1939
|
+
"move-browser": {
|
|
1940
|
+
fn: browserHandlers.moveBrowser,
|
|
1941
|
+
description: "Move browsers to a group"
|
|
1942
|
+
},
|
|
1943
|
+
"get-profile-cookies": {
|
|
1944
|
+
fn: browserHandlers.getProfileCookies,
|
|
1945
|
+
description: "Query and return cookies of the specified profile. Only one profile can be queried per request."
|
|
1946
|
+
},
|
|
1947
|
+
"get-profile-ua": {
|
|
1948
|
+
fn: browserHandlers.getProfileUa,
|
|
1949
|
+
description: "Query and return the User-Agent of specified profiles. Up to 10 profiles can be queried per request."
|
|
1950
|
+
},
|
|
1951
|
+
"close-all-profiles": {
|
|
1952
|
+
fn: browserHandlers.closeAllProfiles,
|
|
1953
|
+
description: "Close all opened profiles on the current device"
|
|
1954
|
+
},
|
|
1955
|
+
"new-fingerprint": {
|
|
1956
|
+
fn: browserHandlers.newFingerprint,
|
|
1957
|
+
description: "Generate a new fingerprint for specified profiles. Up to 10 profiles are supported per request."
|
|
1958
|
+
},
|
|
1959
|
+
"delete-cache-v2": {
|
|
1960
|
+
fn: browserHandlers.deleteCacheV2,
|
|
1961
|
+
description: "Clear local cache of specific profiles.For account security, please ensure that there are no open browsers on the device when using this interface."
|
|
1962
|
+
},
|
|
1963
|
+
"share-profile": {
|
|
1964
|
+
fn: browserHandlers.shareProfile,
|
|
1965
|
+
description: "Share profiles via account email or phone number. The maximum number of profiles that can be shared at one time is 200."
|
|
1966
|
+
},
|
|
1967
|
+
"get-browser-active": {
|
|
1968
|
+
fn: browserHandlers.getBrowserActive,
|
|
1969
|
+
description: "Get active browser profile information"
|
|
1970
|
+
},
|
|
1971
|
+
"get-cloud-active": {
|
|
1972
|
+
fn: browserHandlers.getCloudActive,
|
|
1973
|
+
description: 'Query the status of browser profiles by user_id, up to 100 profiles per request. If the team has enabled "Multi device mode," specific statuses cannot be retrieved and the response will indicate "Profile not opened."'
|
|
1974
|
+
},
|
|
1975
|
+
"create-group": {
|
|
1976
|
+
fn: groupHandlers.createGroup,
|
|
1977
|
+
description: "Create a browser group"
|
|
1978
|
+
},
|
|
1979
|
+
"update-group": {
|
|
1980
|
+
fn: groupHandlers.updateGroup,
|
|
1981
|
+
description: "Update the browser group"
|
|
1982
|
+
},
|
|
1983
|
+
"get-group-list": {
|
|
1984
|
+
fn: groupHandlers.getGroupList,
|
|
1985
|
+
description: "Get the list of groups"
|
|
1986
|
+
},
|
|
1987
|
+
"check-status": {
|
|
1988
|
+
fn: applicationHandlers.checkStatus,
|
|
1989
|
+
description: "Check the availability of the current device API interface (Connection Status)"
|
|
1990
|
+
},
|
|
1991
|
+
"get-application-list": {
|
|
1992
|
+
fn: applicationHandlers.getApplicationList,
|
|
1993
|
+
description: "Get the list of applications (categories)"
|
|
1994
|
+
},
|
|
1995
|
+
"create-proxy": {
|
|
1996
|
+
fn: proxyHandlers.createProxy,
|
|
1997
|
+
description: "Create the proxy"
|
|
1998
|
+
},
|
|
1999
|
+
"update-proxy": {
|
|
2000
|
+
fn: proxyHandlers.updateProxy,
|
|
2001
|
+
description: "Update the proxy"
|
|
2002
|
+
},
|
|
2003
|
+
"get-proxy-list": {
|
|
2004
|
+
fn: proxyHandlers.getProxyList,
|
|
2005
|
+
description: "Get the list of proxies"
|
|
2006
|
+
},
|
|
2007
|
+
"delete-proxy": {
|
|
2008
|
+
fn: proxyHandlers.deleteProxy,
|
|
2009
|
+
description: "Delete the proxy"
|
|
2010
|
+
},
|
|
2011
|
+
"get-tag-list": {
|
|
2012
|
+
fn: tagHandlers.getTagList,
|
|
2013
|
+
description: "Get the list of browser tags"
|
|
2014
|
+
},
|
|
2015
|
+
"create-tag": {
|
|
2016
|
+
fn: tagHandlers.createTag,
|
|
2017
|
+
description: "Create browser tags (batch supported)"
|
|
2018
|
+
},
|
|
2019
|
+
"update-tag": {
|
|
2020
|
+
fn: tagHandlers.updateTag,
|
|
2021
|
+
description: "Update browser tags (batch supported)"
|
|
2022
|
+
},
|
|
2023
|
+
"delete-tag": {
|
|
2024
|
+
fn: tagHandlers.deleteTag,
|
|
2025
|
+
description: "Delete browser tags"
|
|
2026
|
+
},
|
|
2027
|
+
"download-kernel": {
|
|
2028
|
+
fn: kernelHandlers.downloadKernel,
|
|
2029
|
+
description: "Download or update a browser kernel version"
|
|
2030
|
+
},
|
|
2031
|
+
"get-kernel-list": {
|
|
2032
|
+
fn: kernelHandlers.getKernelList,
|
|
2033
|
+
description: "Get browser kernel list by type or all"
|
|
2034
|
+
},
|
|
2035
|
+
"update-patch": {
|
|
2036
|
+
fn: patchHandlers.updatePatch,
|
|
2037
|
+
description: "Update AdsPower to latest patch version"
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
var SINGLE_PROFILE_ID_COMMANDS = {
|
|
2041
|
+
"open-browser": "profileId",
|
|
2042
|
+
"close-browser": "profileId",
|
|
2043
|
+
"get-profile-cookies": "profileId",
|
|
2044
|
+
"get-browser-active": "profileId"
|
|
2045
|
+
};
|
|
2046
|
+
var SINGLE_PROFILE_ID_ARRAY_COMMANDS = ["get-profile-ua", "new-fingerprint"];
|
|
2047
|
+
|
|
2048
|
+
// src/index.ts
|
|
2049
|
+
var program = new import_commander.Command();
|
|
2050
|
+
program.name("adspower-browser").description("CLI and runtime for adspower-browser").version(VERSION);
|
|
2051
|
+
program.command("start").description("Start the adspower runtime").requiredOption("-k, --api-key <apiKey>", "Set the API key for the adspower runtime").addOption(new import_commander.Option("--base-url <baseUrl>", "Set the base URL for the adspower runtime").hideHelp()).addOption(new import_commander.Option("--node-env <nodeEnv>", "Set the node environment for the adspower runtime").hideHelp()).action(async (options) => {
|
|
2052
|
+
if (options.apiKey) {
|
|
2053
|
+
store.setStoreValue("apiKey", options.apiKey);
|
|
2054
|
+
}
|
|
2055
|
+
if (options.baseUrl) {
|
|
2056
|
+
store.setStoreValue("baseUrl", options.baseUrl);
|
|
2057
|
+
}
|
|
2058
|
+
if (options.nodeEnv) {
|
|
2059
|
+
store.setStoreValue("nodeEnv", options.nodeEnv);
|
|
2060
|
+
}
|
|
2061
|
+
await startChild();
|
|
2062
|
+
});
|
|
2063
|
+
program.command("stop").description("Stop the adspower runtime").action(async () => {
|
|
2064
|
+
await stopChild();
|
|
2065
|
+
});
|
|
2066
|
+
program.command("restart").description("Restart the adspower runtime").action(async () => {
|
|
2067
|
+
await restartChild();
|
|
2068
|
+
});
|
|
2069
|
+
program.command("status").description("Get the status of the adspower runtime").action(async () => {
|
|
2070
|
+
getChildStatus();
|
|
2071
|
+
});
|
|
2072
|
+
for (const cmd of Object.keys(STATELESS_HANDLERS)) {
|
|
2073
|
+
const fnc = STATELESS_HANDLERS[cmd].fn;
|
|
2074
|
+
program.command(`${cmd} [params]`).description(STATELESS_HANDLERS[cmd].description).option("-k, --api-key <apiKey>", "Set the API key for the adspower runtime").option("-p, --port <port>", "Set the port for the adspower runtime").action(async (params, options, command) => {
|
|
2075
|
+
const isRun = await hasRunning(options);
|
|
2076
|
+
if (!isRun) {
|
|
2077
|
+
logError("[!] Adspower runtime is not running");
|
|
2078
|
+
const info = `[i] Please run "${(0, import_colors2.green)("adspower-browser start -k <apiKey>")}" to start the adspower runtime`;
|
|
2079
|
+
console.log(info);
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2082
|
+
const { apiKey, port } = getApiKeyAndPort(options);
|
|
2083
|
+
updateConfig(apiKey, port);
|
|
2084
|
+
let args = {};
|
|
2085
|
+
if (params) {
|
|
2086
|
+
const trimmed = params.trim();
|
|
2087
|
+
if (trimmed.startsWith("{")) {
|
|
2088
|
+
try {
|
|
2089
|
+
args = JSON.parse(params);
|
|
2090
|
+
} catch {
|
|
2091
|
+
logError("Invalid JSON for command args");
|
|
2092
|
+
return;
|
|
2093
|
+
}
|
|
2094
|
+
} else if (SINGLE_PROFILE_ID_COMMANDS[command.name()]) {
|
|
2095
|
+
const key = SINGLE_PROFILE_ID_COMMANDS[command.name()];
|
|
2096
|
+
if (!isNaN(Number(trimmed))) {
|
|
2097
|
+
args = { profileNo: Number(trimmed) };
|
|
2098
|
+
} else {
|
|
2099
|
+
args = { profileId: trimmed };
|
|
2100
|
+
}
|
|
2101
|
+
} else if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(command.name())) {
|
|
2102
|
+
args = { profileId: [trimmed] };
|
|
2103
|
+
} else {
|
|
2104
|
+
try {
|
|
2105
|
+
args = JSON.parse(params);
|
|
2106
|
+
} catch {
|
|
2107
|
+
logError(`Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`);
|
|
2108
|
+
return;
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
logSuccess(`Executing command: ${command.name()}, params: ${JSON.stringify(args)}`);
|
|
2113
|
+
const loading = createLoading(`Executing ${command.name()}...`);
|
|
2114
|
+
try {
|
|
2115
|
+
const result = await fnc(args);
|
|
2116
|
+
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
2117
|
+
logInfo(`
|
|
2118
|
+
|
|
2119
|
+
${out}
|
|
2120
|
+
`);
|
|
2121
|
+
if (command.name() === "update-patch") {
|
|
2122
|
+
await sleepTime(1e3 * 60);
|
|
2123
|
+
await restartChild();
|
|
2124
|
+
}
|
|
2125
|
+
} finally {
|
|
2126
|
+
loading.stop();
|
|
2127
|
+
}
|
|
2128
|
+
});
|
|
2129
|
+
}
|
|
2130
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
2131
|
+
console.error(error);
|
|
2132
|
+
process.exit(1);
|
|
2133
|
+
});
|