adspower-browser 1.0.2 → 2.0.0-beta.1
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/README.MD +85 -35
- package/{build/cli.js → cli/index.js} +795 -114
- package/cwd/lib/main.min.js +2 -0
- package/package.json +25 -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
|
@@ -23,6 +23,521 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
mod
|
|
24
24
|
));
|
|
25
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
|
+
if (key === "apiKey" && !this.apiKey) {
|
|
57
|
+
return process.env.ADS_API_KEY || "";
|
|
58
|
+
}
|
|
59
|
+
return this[key];
|
|
60
|
+
}
|
|
61
|
+
setStoreValue(key, value) {
|
|
62
|
+
this[key] = value;
|
|
63
|
+
}
|
|
64
|
+
clear() {
|
|
65
|
+
this.apiKey = "";
|
|
66
|
+
this.baseUrl = "";
|
|
67
|
+
this.nodeEnv = "";
|
|
68
|
+
this.apiPort = "";
|
|
69
|
+
this.appPort = "";
|
|
70
|
+
this.intranet = "";
|
|
71
|
+
this.rpaPid = "";
|
|
72
|
+
this.rpaPlusPid = "";
|
|
73
|
+
this.aiPid = "";
|
|
74
|
+
this.status = "stop";
|
|
75
|
+
this.pid = "";
|
|
76
|
+
}
|
|
77
|
+
getAllStoreValue() {
|
|
78
|
+
return {
|
|
79
|
+
apiKey: this.apiKey,
|
|
80
|
+
baseUrl: this.baseUrl,
|
|
81
|
+
nodeEnv: this.nodeEnv,
|
|
82
|
+
apiPort: this.apiPort,
|
|
83
|
+
appPort: this.appPort,
|
|
84
|
+
intranet: this.intranet,
|
|
85
|
+
rpaPid: this.rpaPid,
|
|
86
|
+
rpaPlusPid: this.rpaPlusPid,
|
|
87
|
+
aiPid: this.aiPid,
|
|
88
|
+
status: this.status,
|
|
89
|
+
pid: this.pid
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
var store = new Store();
|
|
94
|
+
|
|
95
|
+
// src/core/start.ts
|
|
96
|
+
var path2 = __toESM(require("path"));
|
|
97
|
+
var import_node_child_process2 = require("child_process");
|
|
98
|
+
|
|
99
|
+
// src/tools/index.ts
|
|
100
|
+
var os = __toESM(require("os"));
|
|
101
|
+
var path = __toESM(require("path"));
|
|
102
|
+
var fs = __toESM(require("fs"));
|
|
103
|
+
var crypto = __toESM(require("crypto"));
|
|
104
|
+
var util = __toESM(require("util"));
|
|
105
|
+
var import_node_child_process = require("child_process");
|
|
106
|
+
var import_colors = require("colors");
|
|
107
|
+
var import_fs_extra2 = require("fs-extra2");
|
|
108
|
+
var VERSION = "1.0.0";
|
|
109
|
+
var logError = (message) => {
|
|
110
|
+
console.error((0, import_colors.red)(message));
|
|
111
|
+
};
|
|
112
|
+
var logSuccess = (message) => {
|
|
113
|
+
console.log((0, import_colors.green)(message));
|
|
114
|
+
};
|
|
115
|
+
var logWarning = (message) => {
|
|
116
|
+
console.log((0, import_colors.yellow)(message));
|
|
117
|
+
};
|
|
118
|
+
var logInfo = (message) => {
|
|
119
|
+
console.log(message);
|
|
120
|
+
};
|
|
121
|
+
var sleepTime = (time) => new Promise((resolve) => {
|
|
122
|
+
setTimeout(() => {
|
|
123
|
+
resolve();
|
|
124
|
+
}, time);
|
|
125
|
+
});
|
|
126
|
+
var browsersKill = async () => {
|
|
127
|
+
await taskKillBrowser();
|
|
128
|
+
await taskKillFlowser();
|
|
129
|
+
};
|
|
130
|
+
var taskKillBrowser = () => new Promise((resolve) => {
|
|
131
|
+
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "SunBrowser"' : "taskkill -PID SunBrowser.exe";
|
|
132
|
+
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
133
|
+
if (err) {
|
|
134
|
+
}
|
|
135
|
+
resolve();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
var taskKillFlowser = () => new Promise((resolve) => {
|
|
139
|
+
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "FlowerBrowser"' : "taskkill -PID FlowerBrowser.exe";
|
|
140
|
+
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
141
|
+
if (err) {
|
|
142
|
+
}
|
|
143
|
+
resolve();
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
var getHomedir = () => {
|
|
147
|
+
return (typeof os.homedir == "function" ? os.homedir() : process.env[process.platform == "win32" ? "USERPROFILE" : "HOME"]) || "~";
|
|
148
|
+
};
|
|
149
|
+
var getPidFileDir = () => {
|
|
150
|
+
const dir = path.join(getHomedir(), ".adspowerCli");
|
|
151
|
+
if (!fs.existsSync(dir)) {
|
|
152
|
+
(0, import_fs_extra2.ensureDirSync)(dir);
|
|
153
|
+
}
|
|
154
|
+
return dir;
|
|
155
|
+
};
|
|
156
|
+
var pidFileName = () => {
|
|
157
|
+
const md5 = crypto.createHash("md5").update(VERSION).digest("hex");
|
|
158
|
+
return md5;
|
|
159
|
+
};
|
|
160
|
+
var writePidFile = (config2) => {
|
|
161
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
162
|
+
(0, import_fs_extra2.outputJsonSync)(filePath, config2 || {});
|
|
163
|
+
};
|
|
164
|
+
var readPidFile = () => {
|
|
165
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
166
|
+
if (fs.existsSync(filePath)) {
|
|
167
|
+
return (0, import_fs_extra2.readJsonSync)(filePath);
|
|
168
|
+
}
|
|
169
|
+
return {};
|
|
170
|
+
};
|
|
171
|
+
var removePidFile = () => {
|
|
172
|
+
const filePath = path.join(getPidFileDir(), pidFileName());
|
|
173
|
+
if (fs.existsSync(filePath)) {
|
|
174
|
+
(0, import_fs_extra2.removeSync)(filePath);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
var isRunning = (pid) => {
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
if (pid) {
|
|
180
|
+
(0, import_node_child_process.exec)(
|
|
181
|
+
util.format(process.platform === "win32" ? 'tasklist /fi "PID eq %s" | findstr /i "node.exe"' : 'ps -f -p %s | grep "node"', pid),
|
|
182
|
+
function(err, stdout, stderr) {
|
|
183
|
+
resolve(!err && !!stdout.toString().trim());
|
|
184
|
+
}
|
|
185
|
+
);
|
|
186
|
+
} else {
|
|
187
|
+
resolve(false);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
};
|
|
191
|
+
var ensureBrowserPath = () => {
|
|
192
|
+
const dir = path.join(__dirname, "../cwd/source", ".browser");
|
|
193
|
+
if (!fs.existsSync(dir)) {
|
|
194
|
+
(0, import_fs_extra2.ensureDirSync)(dir);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
var getApiKeyAndPort = (options) => {
|
|
198
|
+
const apiKey = options.apiKey;
|
|
199
|
+
const port = options.port;
|
|
200
|
+
if (apiKey && port) {
|
|
201
|
+
return {
|
|
202
|
+
apiKey,
|
|
203
|
+
port
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
const result = {
|
|
207
|
+
apiKey,
|
|
208
|
+
port
|
|
209
|
+
};
|
|
210
|
+
const processInstance = readPidFile();
|
|
211
|
+
if (!apiKey) {
|
|
212
|
+
if (processInstance.apiKey) {
|
|
213
|
+
result.apiKey = processInstance.apiKey;
|
|
214
|
+
} else if (process.env.ADS_API_KEY) {
|
|
215
|
+
result.apiKey = process.env.ADS_API_KEY;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (!port && processInstance.apiPort) {
|
|
219
|
+
result.port = processInstance.apiPort;
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
};
|
|
223
|
+
var hasRunning = async (options) => {
|
|
224
|
+
const { apiKey, port } = options;
|
|
225
|
+
if (apiKey && port) {
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
const processInstance = readPidFile();
|
|
229
|
+
if (processInstance.pid) {
|
|
230
|
+
return await isRunning(processInstance.pid);
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
};
|
|
234
|
+
var loadingFramesList = {
|
|
235
|
+
default: ["|", "/", "-", "\\"],
|
|
236
|
+
frames: ["\u2596", "\u2597", "\u2598", "\u2599", "\u259A", "\u259B", "\u259C", "\u259D", "\u259E", "\u259F"],
|
|
237
|
+
dotFrames: ["\u2840", "\u2844", "\u2846", "\u2847", "\u284F", "\u285F", "\u287F", "\u28FF", "\u28F7", "\u28F6", "\u28E6", "\u28E4", "\u28E0", "\u2880"]
|
|
238
|
+
};
|
|
239
|
+
var createLoading = (text) => {
|
|
240
|
+
if (!process.stdout.isTTY) {
|
|
241
|
+
return {
|
|
242
|
+
stop() {
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
let index = 0;
|
|
247
|
+
const frames = loadingFramesList.default;
|
|
248
|
+
process.stdout.write(`${frames[index]} ${text}`);
|
|
249
|
+
const timer = setInterval(() => {
|
|
250
|
+
index = (index + 1) % frames.length;
|
|
251
|
+
process.stdout.write(`\r${frames[index]} ${text}`);
|
|
252
|
+
}, 120);
|
|
253
|
+
return {
|
|
254
|
+
stop() {
|
|
255
|
+
clearInterval(timer);
|
|
256
|
+
process.stdout.write(`\r${" ".repeat(text.length + 2)}\r`);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
};
|
|
260
|
+
var initSqlite3 = () => {
|
|
261
|
+
const sqliteFile = path.join(__dirname, "../cwd/lib", "node_sqlite3.node");
|
|
262
|
+
if (fs.existsSync(sqliteFile)) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
const isMac = process.platform === "darwin";
|
|
266
|
+
const isLinux = process.platform === "linux";
|
|
267
|
+
const is32 = process.arch === "ia32";
|
|
268
|
+
const isArm = process.arch === "arm64";
|
|
269
|
+
const isX64 = process.arch === "x64";
|
|
270
|
+
const macFolder = isArm ? "arm64" : "mac";
|
|
271
|
+
const winFolder = is32 ? "ia32" : "x64";
|
|
272
|
+
const linuxFolder = isLinux && isX64 && "linux";
|
|
273
|
+
const sqliteFolder = isMac ? macFolder : isLinux ? linuxFolder : winFolder;
|
|
274
|
+
const dir = path.join(__dirname, `../sqlite/${sqliteFolder}`);
|
|
275
|
+
if (!fs.existsSync(dir)) {
|
|
276
|
+
throw new Error(`SQLite folder not found: ${dir}`);
|
|
277
|
+
} else {
|
|
278
|
+
const sqliteFile2 = path.join(dir, "node_sqlite3.node");
|
|
279
|
+
const cwdPath = path.join(__dirname, "../cwd/lib");
|
|
280
|
+
(0, import_fs_extra2.copySync)(sqliteFile2, path.join(cwdPath, "node_sqlite3.node"));
|
|
281
|
+
logSuccess(`[i] SQLite file initialized successfully!`);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
var renderKernelProgress = (result) => {
|
|
285
|
+
const status = result.status || "pending";
|
|
286
|
+
const progress = ["completed", "installing"].includes(status) ? 100 : Math.max(0, Math.min(100, Number(result.progress) || 0));
|
|
287
|
+
if (!process.stdout.isTTY) {
|
|
288
|
+
logInfo(`Kernel progress: ${progress}% [${status}]`);
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const width = 30;
|
|
292
|
+
const filled = Math.round(progress / 100 * width);
|
|
293
|
+
const bar = `${"=".repeat(filled)}${"-".repeat(width - filled)}`;
|
|
294
|
+
process.stdout.write(`\r[${bar}] ${progress.toFixed(0).padStart(3, " ")}% ${status} `);
|
|
295
|
+
};
|
|
296
|
+
var finishKernelProgress = () => {
|
|
297
|
+
if (process.stdout.isTTY) {
|
|
298
|
+
process.stdout.write("\n");
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
var trackKernelDownload = async (fnc, args) => {
|
|
302
|
+
while (true) {
|
|
303
|
+
const result = await fnc(args);
|
|
304
|
+
try {
|
|
305
|
+
const resultJson = JSON.parse(result.replace("Kernel download/update status: ", ""));
|
|
306
|
+
if (resultJson && resultJson.status && ["pending", "downloading", "completed", "installing", "failed"].includes(resultJson.status)) {
|
|
307
|
+
renderKernelProgress(resultJson);
|
|
308
|
+
if (["completed", "failed"].includes(resultJson.status)) {
|
|
309
|
+
finishKernelProgress();
|
|
310
|
+
return result;
|
|
311
|
+
}
|
|
312
|
+
await sleepTime(3e3);
|
|
313
|
+
} else {
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
return result;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/core/start.ts
|
|
323
|
+
var getEnv = () => {
|
|
324
|
+
const env = {
|
|
325
|
+
...process.env,
|
|
326
|
+
// 系统的环境变量信息
|
|
327
|
+
API_KEY: store.getStoreValue("apiKey"),
|
|
328
|
+
IS_CLOUD_BROWSER: true
|
|
329
|
+
// 云浏览器场景预留标识
|
|
330
|
+
};
|
|
331
|
+
if (store.getStoreValue("baseUrl")) {
|
|
332
|
+
env.BASE_URL = store.getStoreValue("baseUrl");
|
|
333
|
+
}
|
|
334
|
+
if (store.getStoreValue("nodeEnv")) {
|
|
335
|
+
env.NODE_ENV = store.getStoreValue("nodeEnv");
|
|
336
|
+
}
|
|
337
|
+
return env;
|
|
338
|
+
};
|
|
339
|
+
var startChild = (type) => {
|
|
340
|
+
let timer;
|
|
341
|
+
let child = null;
|
|
342
|
+
return new Promise(async (resolve, reject) => {
|
|
343
|
+
initSqlite3();
|
|
344
|
+
const processInstance = readPidFile();
|
|
345
|
+
if (processInstance && processInstance.pid) {
|
|
346
|
+
const isRun = await isRunning(processInstance.pid);
|
|
347
|
+
removePidFile();
|
|
348
|
+
if (isRun) {
|
|
349
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
350
|
+
await sleepTime(1e3);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const env = Object.fromEntries(
|
|
354
|
+
Object.entries(getEnv()).map(([key, value]) => [key, value == null ? value : String(value)])
|
|
355
|
+
);
|
|
356
|
+
try {
|
|
357
|
+
const mainJs = path2.join(__dirname, "../cwd/lib", "main.min.js");
|
|
358
|
+
child = (0, import_node_child_process2.fork)(mainJs, {
|
|
359
|
+
env,
|
|
360
|
+
detached: true,
|
|
361
|
+
stdio: ["ignore", "ignore", "ignore", "ipc"]
|
|
362
|
+
});
|
|
363
|
+
ensureBrowserPath();
|
|
364
|
+
store.setStoreValue("status", "starting");
|
|
365
|
+
logSuccess(`[i] Adspower program is starting...`);
|
|
366
|
+
store.setStoreValue("pid", child?.pid?.toString() || "");
|
|
367
|
+
let isAppPortOk = false;
|
|
368
|
+
writePidFile(store.getAllStoreValue());
|
|
369
|
+
child.on("message", async (msg) => {
|
|
370
|
+
const text = String(msg);
|
|
371
|
+
if (text.indexOf("SERVER_PORT_$$_") === 0 && !isAppPortOk) {
|
|
372
|
+
const port = text.replace("SERVER_PORT_$$_", "").trim();
|
|
373
|
+
store.setStoreValue("appPort", port);
|
|
374
|
+
isAppPortOk = true;
|
|
375
|
+
}
|
|
376
|
+
if (text.indexOf("START_API_SERVER_SUCCESS_$$_") === 0) {
|
|
377
|
+
const port = text.replace("START_API_SERVER_SUCCESS_$$_", "").trim();
|
|
378
|
+
store.setStoreValue("apiPort", port);
|
|
379
|
+
logSuccess(`Server running at:`);
|
|
380
|
+
logSuccess(` - local: http://local.adspower.net:${port}`);
|
|
381
|
+
writePidFile(store.getAllStoreValue());
|
|
382
|
+
if (child) {
|
|
383
|
+
child.disconnect();
|
|
384
|
+
child.unref();
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (text.indexOf("START_API_SERVER_FAIL_$$_") === 0) {
|
|
388
|
+
const serverMsg = text.replace("START_API_SERVER_FAIL_$$_", "").split("_").filter(Boolean);
|
|
389
|
+
if (serverMsg[0]) {
|
|
390
|
+
logError(`ERROR - ${serverMsg[0]}`);
|
|
391
|
+
}
|
|
392
|
+
if (serverMsg[1]) {
|
|
393
|
+
logError(`ERROR - ${serverMsg[1]}`);
|
|
394
|
+
}
|
|
395
|
+
process.exit(0);
|
|
396
|
+
}
|
|
397
|
+
if (text === "start") {
|
|
398
|
+
clearTimeout(timer);
|
|
399
|
+
resolve();
|
|
400
|
+
store.setStoreValue("status", "doing");
|
|
401
|
+
writePidFile(store.getAllStoreValue());
|
|
402
|
+
}
|
|
403
|
+
if (text === "restart") {
|
|
404
|
+
child && child.kill("SIGKILL");
|
|
405
|
+
store.setStoreValue("status", "restarting");
|
|
406
|
+
startChild("2").catch(() => {
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (text.indexOf("INTRANET_$$_") > -1) {
|
|
410
|
+
const arr = text.split("_$$_");
|
|
411
|
+
if (arr && arr[1]) {
|
|
412
|
+
store.setStoreValue("intranet", arr[1]);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
if (text === "browser-kill") {
|
|
416
|
+
await browsersKill();
|
|
417
|
+
}
|
|
418
|
+
if (text.indexOf("RPA_PROCESS_PID_") > -1) {
|
|
419
|
+
const rpaPid = text.replace("RPA_PROCESS_PID_", "");
|
|
420
|
+
store.setStoreValue("rpaPid", rpaPid);
|
|
421
|
+
}
|
|
422
|
+
if (text.indexOf("RPA_PLUS_PROCESS_PID_") > -1) {
|
|
423
|
+
const rpaPlusPid = text.replace("RPA_PLUS_PROCESS_PID_", "");
|
|
424
|
+
store.setStoreValue("rpaPlusPid", rpaPlusPid);
|
|
425
|
+
}
|
|
426
|
+
if (text.indexOf("AI_PROCESS_PID_") > -1) {
|
|
427
|
+
const aiPid = text.replace("AI_PROCESS_PID_", "");
|
|
428
|
+
store.setStoreValue("aiPid", aiPid);
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
child.on("error", (err) => {
|
|
432
|
+
logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${err.message}`);
|
|
433
|
+
store.setStoreValue("status", "stop");
|
|
434
|
+
store.clear();
|
|
435
|
+
removePidFile();
|
|
436
|
+
process.exit(0);
|
|
437
|
+
});
|
|
438
|
+
child.on("exit", async (code, signal) => {
|
|
439
|
+
if (signal === "SIGKILL") {
|
|
440
|
+
await browsersKill();
|
|
441
|
+
store.clear();
|
|
442
|
+
removePidFile();
|
|
443
|
+
} else {
|
|
444
|
+
child = null;
|
|
445
|
+
await sleepTime(500);
|
|
446
|
+
startChild("2").then(() => {
|
|
447
|
+
}).catch(() => {
|
|
448
|
+
logError("[!] Restart failed");
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
timer = setTimeout(() => {
|
|
453
|
+
child && child.kill("SIGKILL");
|
|
454
|
+
child = null;
|
|
455
|
+
store.setStoreValue("status", "stop");
|
|
456
|
+
logError("[!] Start Timeout");
|
|
457
|
+
reject("Start Timeout");
|
|
458
|
+
}, 30 * 1e3);
|
|
459
|
+
} catch (error) {
|
|
460
|
+
clearTimeout(timer);
|
|
461
|
+
reject(error);
|
|
462
|
+
child = null;
|
|
463
|
+
store.clear();
|
|
464
|
+
logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
};
|
|
468
|
+
var stopChild = async () => {
|
|
469
|
+
const processInstance = readPidFile();
|
|
470
|
+
if (processInstance.pid) {
|
|
471
|
+
const isRun = await isRunning(processInstance.pid);
|
|
472
|
+
try {
|
|
473
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
474
|
+
removePidFile();
|
|
475
|
+
} catch (error) {
|
|
476
|
+
try {
|
|
477
|
+
await sleepTime(2e3);
|
|
478
|
+
process.kill(Number(processInstance.pid), "SIGKILL");
|
|
479
|
+
removePidFile();
|
|
480
|
+
} catch (error2) {
|
|
481
|
+
logError(`[!] Stop child fail: ${error2 instanceof Error ? error2.message : JSON.stringify(error2)}`);
|
|
482
|
+
if (isRun) {
|
|
483
|
+
logWarning(`[!] Please manually close the browser process: ${processInstance.pid}`);
|
|
484
|
+
}
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
logSuccess("[i] Adspower program is stopped");
|
|
489
|
+
} else {
|
|
490
|
+
logInfo("[i] No running adspower program");
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
var restartChild = async () => {
|
|
494
|
+
const processInstance = readPidFile();
|
|
495
|
+
if (processInstance.pid) {
|
|
496
|
+
const apiKey = processInstance.apiKey;
|
|
497
|
+
const baseUrl = processInstance.baseUrl;
|
|
498
|
+
const nodeEnv = processInstance.nodeEnv;
|
|
499
|
+
await stopChild();
|
|
500
|
+
await sleepTime(1e3);
|
|
501
|
+
store.setStoreValue("apiKey", apiKey);
|
|
502
|
+
store.setStoreValue("baseUrl", baseUrl);
|
|
503
|
+
store.setStoreValue("nodeEnv", nodeEnv);
|
|
504
|
+
await startChild().then(() => {
|
|
505
|
+
logSuccess("[i] Adspower program is restarted");
|
|
506
|
+
}).catch((error) => {
|
|
507
|
+
logError(`[!] Restart failed: ${error.message}`);
|
|
508
|
+
});
|
|
509
|
+
} else {
|
|
510
|
+
logInfo("[i] No running adspower program");
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
var getChildStatus = async () => {
|
|
514
|
+
const processInstance = readPidFile();
|
|
515
|
+
if (processInstance.pid) {
|
|
516
|
+
const isRun = await isRunning(processInstance.pid);
|
|
517
|
+
if (!isRun) {
|
|
518
|
+
removePidFile();
|
|
519
|
+
logInfo("[i] Adspower program is not running");
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const status = processInstance.status;
|
|
523
|
+
if (status === "starting") {
|
|
524
|
+
logSuccess("[i] Adspower program is starting...");
|
|
525
|
+
} else if (status === "doing" && processInstance.apiPort) {
|
|
526
|
+
logSuccess("[i] Adspower program is running at:");
|
|
527
|
+
logSuccess(` - http://local.adspower.net:${processInstance.apiPort}`);
|
|
528
|
+
} else if (status === "stop") {
|
|
529
|
+
logInfo("[i] Adspower program is stopped");
|
|
530
|
+
} else {
|
|
531
|
+
logInfo("[i] Adspower program is not started");
|
|
532
|
+
}
|
|
533
|
+
} else {
|
|
534
|
+
logInfo("[i] Adspower program is not running");
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
// src/index.ts
|
|
539
|
+
var import_colors2 = require("colors");
|
|
540
|
+
|
|
26
541
|
// ../core/src/constants/api.ts
|
|
27
542
|
var import_axios = __toESM(require("axios"));
|
|
28
543
|
|
|
@@ -40,16 +555,28 @@ function parseArgs() {
|
|
|
40
555
|
}
|
|
41
556
|
}
|
|
42
557
|
return {
|
|
43
|
-
port: port || process.env.PORT || "
|
|
558
|
+
port: port || process.env.PORT || "50326",
|
|
44
559
|
apiKey: apiKey || process.env.API_KEY
|
|
45
560
|
};
|
|
46
561
|
}
|
|
47
562
|
var config = parseArgs();
|
|
563
|
+
var updateConfig = (apiKey, port) => {
|
|
564
|
+
if (apiKey) {
|
|
565
|
+
config.apiKey = apiKey;
|
|
566
|
+
}
|
|
567
|
+
if (port) {
|
|
568
|
+
config.port = port;
|
|
569
|
+
}
|
|
570
|
+
};
|
|
48
571
|
var PORT = config.port;
|
|
49
572
|
var API_KEY = config.apiKey;
|
|
573
|
+
var CONFIG = config;
|
|
50
574
|
|
|
51
575
|
// ../core/src/constants/api.ts
|
|
52
576
|
var LOCAL_API_BASE = `http://127.0.0.1:${PORT}`;
|
|
577
|
+
var getLocalApiBase = () => {
|
|
578
|
+
return `http://127.0.0.1:${CONFIG.port}`;
|
|
579
|
+
};
|
|
53
580
|
var API_ENDPOINTS = {
|
|
54
581
|
STATUS: "/status",
|
|
55
582
|
START_BROWSER: "/api/v2/browser-profile/start",
|
|
@@ -87,6 +614,11 @@ var API_ENDPOINTS = {
|
|
|
87
614
|
var apiClient = import_axios.default.create({
|
|
88
615
|
headers: API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {}
|
|
89
616
|
});
|
|
617
|
+
var getApiClient = () => {
|
|
618
|
+
return import_axios.default.create({
|
|
619
|
+
headers: CONFIG.apiKey ? { "Authorization": `Bearer ${CONFIG.apiKey}` } : {}
|
|
620
|
+
});
|
|
621
|
+
};
|
|
90
622
|
|
|
91
623
|
// ../core/src/utils/requestBuilder.ts
|
|
92
624
|
function buildRequestBody(params) {
|
|
@@ -174,7 +706,7 @@ var browserHandlers = {
|
|
|
174
706
|
if (cdpMask) {
|
|
175
707
|
requestBody.cdp_mask = cdpMask;
|
|
176
708
|
}
|
|
177
|
-
const response = await
|
|
709
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.START_BROWSER}`, requestBody);
|
|
178
710
|
if (response.data.code === 0) {
|
|
179
711
|
return `Browser opened successfully with: ${Object.entries(response.data.data).map(([key, value]) => {
|
|
180
712
|
if (value && typeof value === "object") {
|
|
@@ -193,7 +725,7 @@ var browserHandlers = {
|
|
|
193
725
|
if (profileNo) {
|
|
194
726
|
requestBody.profile_no = profileNo;
|
|
195
727
|
}
|
|
196
|
-
const response = await
|
|
728
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_BROWSER}`, requestBody);
|
|
197
729
|
if (response.data.code === 0) {
|
|
198
730
|
return "Browser closed successfully";
|
|
199
731
|
}
|
|
@@ -201,7 +733,7 @@ var browserHandlers = {
|
|
|
201
733
|
},
|
|
202
734
|
async createBrowser(params) {
|
|
203
735
|
const requestBody = buildRequestBody(params);
|
|
204
|
-
const response = await
|
|
736
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_BROWSER}`, requestBody);
|
|
205
737
|
if (response.data.code === 0) {
|
|
206
738
|
return `Browser created successfully with: ${Object.entries(response.data.data).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
207
739
|
}
|
|
@@ -209,14 +741,14 @@ var browserHandlers = {
|
|
|
209
741
|
},
|
|
210
742
|
async updateBrowser(params) {
|
|
211
743
|
const requestBody = buildRequestBody(params);
|
|
212
|
-
const response = await
|
|
744
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_BROWSER}`, requestBody);
|
|
213
745
|
if (response.data.code === 0) {
|
|
214
746
|
return `Browser updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
215
747
|
}
|
|
216
748
|
throw new Error(`Failed to update browser: ${response.data.msg}`);
|
|
217
749
|
},
|
|
218
750
|
async deleteBrowser({ profileIds }) {
|
|
219
|
-
const response = await
|
|
751
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_BROWSER}`, {
|
|
220
752
|
profile_id: profileIds
|
|
221
753
|
});
|
|
222
754
|
if (response.data.code === 0) {
|
|
@@ -260,21 +792,21 @@ var browserHandlers = {
|
|
|
260
792
|
if (name_filter) {
|
|
261
793
|
requestBody.name_filter = name_filter;
|
|
262
794
|
}
|
|
263
|
-
const response = await
|
|
795
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_LIST}`, requestBody);
|
|
264
796
|
if (response.data.code === 0) {
|
|
265
797
|
return `Browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
266
798
|
}
|
|
267
799
|
throw new Error(`Failed to get browser list: ${response.data.msg}`);
|
|
268
800
|
},
|
|
269
801
|
async getOpenedBrowser() {
|
|
270
|
-
const response = await
|
|
802
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_OPENED_BROWSER}`);
|
|
271
803
|
if (response.data.code === 0) {
|
|
272
804
|
return `Opened browser list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
273
805
|
}
|
|
274
806
|
throw new Error(`Failed to get opened browsers: ${response.data.msg}`);
|
|
275
807
|
},
|
|
276
808
|
async moveBrowser({ groupId, userIds }) {
|
|
277
|
-
const response = await
|
|
809
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.MOVE_BROWSER}`, {
|
|
278
810
|
group_id: groupId,
|
|
279
811
|
user_ids: userIds
|
|
280
812
|
});
|
|
@@ -291,7 +823,7 @@ var browserHandlers = {
|
|
|
291
823
|
if (profileNo) {
|
|
292
824
|
params.set("profile_no", profileNo);
|
|
293
825
|
}
|
|
294
|
-
const response = await
|
|
826
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_COOKIES}`, { params });
|
|
295
827
|
if (response.data.code === 0) {
|
|
296
828
|
return `Profile cookies: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
297
829
|
}
|
|
@@ -305,14 +837,14 @@ var browserHandlers = {
|
|
|
305
837
|
if (profileNo && profileNo.length > 0) {
|
|
306
838
|
requestBody.profile_no = profileNo;
|
|
307
839
|
}
|
|
308
|
-
const response = await
|
|
840
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROFILE_UA}`, requestBody);
|
|
309
841
|
if (response.data.code === 0) {
|
|
310
842
|
return `Profile User-Agent: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
311
843
|
}
|
|
312
844
|
throw new Error(`Failed to get profile User-Agent: ${response.data.msg}`);
|
|
313
845
|
},
|
|
314
846
|
async closeAllProfiles(_params) {
|
|
315
|
-
const response = await
|
|
847
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CLOSE_ALL_PROFILES}`, {});
|
|
316
848
|
if (response.data.code === 0) {
|
|
317
849
|
return "All profiles closed successfully";
|
|
318
850
|
}
|
|
@@ -326,14 +858,14 @@ var browserHandlers = {
|
|
|
326
858
|
if (profileNo && profileNo.length > 0) {
|
|
327
859
|
requestBody.profile_no = profileNo;
|
|
328
860
|
}
|
|
329
|
-
const response = await
|
|
861
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.NEW_FINGERPRINT}`, requestBody);
|
|
330
862
|
if (response.data.code === 0) {
|
|
331
863
|
return `New fingerprint created: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
332
864
|
}
|
|
333
865
|
throw new Error(`Failed to create new fingerprint: ${response.data.msg}`);
|
|
334
866
|
},
|
|
335
867
|
async deleteCacheV2({ profileIds, type }) {
|
|
336
|
-
const response = await
|
|
868
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_CACHE_V2}`, {
|
|
337
869
|
profile_id: profileIds,
|
|
338
870
|
type
|
|
339
871
|
});
|
|
@@ -353,7 +885,7 @@ var browserHandlers = {
|
|
|
353
885
|
if (content !== void 0) {
|
|
354
886
|
requestBody.content = content;
|
|
355
887
|
}
|
|
356
|
-
const response = await
|
|
888
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.SHARE_PROFILE}`, requestBody);
|
|
357
889
|
if (response.data.code === 0) {
|
|
358
890
|
return `Profiles shared successfully: ${profileIds.join(", ")}`;
|
|
359
891
|
}
|
|
@@ -367,14 +899,14 @@ var browserHandlers = {
|
|
|
367
899
|
if (profileNo) {
|
|
368
900
|
params.set("profile_no", profileNo);
|
|
369
901
|
}
|
|
370
|
-
const response = await
|
|
902
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_BROWSER_ACTIVE}`, { params });
|
|
371
903
|
if (response.data.code === 0) {
|
|
372
904
|
return `Browser active info: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
373
905
|
}
|
|
374
906
|
throw new Error(`Failed to get browser active: ${response.data.msg}`);
|
|
375
907
|
},
|
|
376
908
|
async getCloudActive({ userIds }) {
|
|
377
|
-
const response = await
|
|
909
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_CLOUD_ACTIVE}`, {
|
|
378
910
|
user_ids: userIds
|
|
379
911
|
});
|
|
380
912
|
if (response.data.code === 0) {
|
|
@@ -393,7 +925,7 @@ var groupHandlers = {
|
|
|
393
925
|
if (remark !== void 0) {
|
|
394
926
|
requestBody.remark = remark;
|
|
395
927
|
}
|
|
396
|
-
const response = await
|
|
928
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_GROUP}`, requestBody);
|
|
397
929
|
if (response.data.code === 0) {
|
|
398
930
|
return `Group created successfully with name: ${groupName}${remark ? `, remark: ${remark}` : ""}`;
|
|
399
931
|
}
|
|
@@ -407,7 +939,7 @@ var groupHandlers = {
|
|
|
407
939
|
if (remark !== void 0) {
|
|
408
940
|
requestBody.remark = remark;
|
|
409
941
|
}
|
|
410
|
-
const response = await
|
|
942
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_GROUP}`, requestBody);
|
|
411
943
|
if (response.data.code === 0) {
|
|
412
944
|
return `Group updated successfully with id: ${groupId}, name: ${groupName}${remark !== void 0 ? `, remark: ${remark === null ? "(cleared)" : remark}` : ""}`;
|
|
413
945
|
}
|
|
@@ -424,7 +956,7 @@ var groupHandlers = {
|
|
|
424
956
|
if (page) {
|
|
425
957
|
params.set("page", page.toString());
|
|
426
958
|
}
|
|
427
|
-
const response = await
|
|
959
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_GROUP_LIST}`, { params });
|
|
428
960
|
return `Group list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
429
961
|
}
|
|
430
962
|
};
|
|
@@ -432,7 +964,7 @@ var groupHandlers = {
|
|
|
432
964
|
// ../core/src/handlers/application.ts
|
|
433
965
|
var applicationHandlers = {
|
|
434
966
|
async checkStatus() {
|
|
435
|
-
const response = await
|
|
967
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.STATUS}`);
|
|
436
968
|
return `Connection status: ${JSON.stringify(response.data, null, 2)}`;
|
|
437
969
|
},
|
|
438
970
|
async getApplicationList({ category_id, page, limit }) {
|
|
@@ -446,7 +978,7 @@ var applicationHandlers = {
|
|
|
446
978
|
if (limit !== void 0) {
|
|
447
979
|
params.set("limit", limit.toString());
|
|
448
980
|
}
|
|
449
|
-
const response = await
|
|
981
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_APPLICATION_LIST}`, { params });
|
|
450
982
|
return `Application list: ${JSON.stringify(response.data.data.list, null, 2)}`;
|
|
451
983
|
}
|
|
452
984
|
};
|
|
@@ -508,7 +1040,7 @@ function buildCreateProxyRequestBody(proxy) {
|
|
|
508
1040
|
var proxyHandlers = {
|
|
509
1041
|
async createProxy(params) {
|
|
510
1042
|
const requestBody = params.proxies.map((proxy) => buildCreateProxyRequestBody(proxy));
|
|
511
|
-
const response = await
|
|
1043
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_PROXY}`, requestBody);
|
|
512
1044
|
if (response.data.code === 0) {
|
|
513
1045
|
return `Proxy created successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
514
1046
|
}
|
|
@@ -516,7 +1048,7 @@ var proxyHandlers = {
|
|
|
516
1048
|
},
|
|
517
1049
|
async updateProxy(params) {
|
|
518
1050
|
const requestBody = buildProxyRequestBody(params);
|
|
519
|
-
const response = await
|
|
1051
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PROXY}`, requestBody);
|
|
520
1052
|
if (response.data.code === 0) {
|
|
521
1053
|
return `Proxy updated successfully with: ${Object.entries(response.data.data || {}).map(([key, value]) => `${key}: ${value}`).join("\n")}`;
|
|
522
1054
|
}
|
|
@@ -534,14 +1066,14 @@ var proxyHandlers = {
|
|
|
534
1066
|
if (proxyId && proxyId.length > 0) {
|
|
535
1067
|
requestBody.proxy_id = proxyId;
|
|
536
1068
|
}
|
|
537
|
-
const response = await
|
|
1069
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_PROXY_LIST}`, requestBody);
|
|
538
1070
|
if (response.data.code === 0) {
|
|
539
1071
|
return `Proxy list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
540
1072
|
}
|
|
541
1073
|
throw new Error(`Failed to get proxy list: ${response.data.msg}`);
|
|
542
1074
|
},
|
|
543
1075
|
async deleteProxy({ proxyIds }) {
|
|
544
|
-
const response = await
|
|
1076
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_PROXY}`, {
|
|
545
1077
|
proxy_id: proxyIds
|
|
546
1078
|
});
|
|
547
1079
|
if (response.data.code === 0) {
|
|
@@ -565,28 +1097,28 @@ var tagHandlers = {
|
|
|
565
1097
|
if (page !== void 0) {
|
|
566
1098
|
requestBody.page = page;
|
|
567
1099
|
}
|
|
568
|
-
const response = await
|
|
1100
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.GET_TAG_LIST}`, requestBody);
|
|
569
1101
|
if (response.data.code === 0) {
|
|
570
1102
|
return `Tag list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
571
1103
|
}
|
|
572
1104
|
throw new Error(`Failed to get tag list: ${response.data.msg}`);
|
|
573
1105
|
},
|
|
574
1106
|
async createTag({ tags }) {
|
|
575
|
-
const response = await
|
|
1107
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.CREATE_TAG}`, { tags });
|
|
576
1108
|
if (response.data.code === 0) {
|
|
577
1109
|
return `Tags created successfully: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
578
1110
|
}
|
|
579
1111
|
throw new Error(`Failed to create tags: ${response.data.msg}`);
|
|
580
1112
|
},
|
|
581
1113
|
async updateTag({ tags }) {
|
|
582
|
-
const response = await
|
|
1114
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_TAG}`, { tags });
|
|
583
1115
|
if (response.data.code === 0) {
|
|
584
1116
|
return `Tags updated successfully: ${JSON.stringify(response.data.data, null, 2)}`;
|
|
585
1117
|
}
|
|
586
1118
|
throw new Error(`Failed to update tags: ${response.data.msg}`);
|
|
587
1119
|
},
|
|
588
1120
|
async deleteTag({ ids }) {
|
|
589
|
-
const response = await
|
|
1121
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DELETE_TAG}`, { ids });
|
|
590
1122
|
if (response.data.code === 0) {
|
|
591
1123
|
return `Tags deleted successfully: ${ids.join(", ")}`;
|
|
592
1124
|
}
|
|
@@ -654,7 +1186,7 @@ var defaultDownloadsPath = import_path.default.join(import_os.default.homedir(),
|
|
|
654
1186
|
// ../core/src/handlers/kernel.ts
|
|
655
1187
|
var kernelHandlers = {
|
|
656
1188
|
async downloadKernel({ kernel_type, kernel_version }) {
|
|
657
|
-
const response = await
|
|
1189
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.DOWNLOAD_KERNEL}`, {
|
|
658
1190
|
kernel_type,
|
|
659
1191
|
kernel_version
|
|
660
1192
|
});
|
|
@@ -668,7 +1200,7 @@ var kernelHandlers = {
|
|
|
668
1200
|
if (kernel_type) {
|
|
669
1201
|
params.set("kernel_type", kernel_type);
|
|
670
1202
|
}
|
|
671
|
-
const response = await
|
|
1203
|
+
const response = await getApiClient().get(`${getLocalApiBase()}${API_ENDPOINTS.GET_KERNEL_LIST}`, { params });
|
|
672
1204
|
if (response.data.code === 0) {
|
|
673
1205
|
return `Kernel list: ${JSON.stringify(response.data.data.list || response.data.data, null, 2)}`;
|
|
674
1206
|
}
|
|
@@ -683,7 +1215,7 @@ var patchHandlers = {
|
|
|
683
1215
|
if (version_type) {
|
|
684
1216
|
requestBody.version_type = version_type;
|
|
685
1217
|
}
|
|
686
|
-
const response = await
|
|
1218
|
+
const response = await getApiClient().post(`${getLocalApiBase()}${API_ENDPOINTS.UPDATE_PATCH}`, requestBody);
|
|
687
1219
|
if (response.data.code === 0) {
|
|
688
1220
|
return `Patch update status: ${JSON.stringify(response.data.data, null, 2)}, message: ${response.data.msg}`;
|
|
689
1221
|
}
|
|
@@ -1420,38 +1952,134 @@ var schemas = {
|
|
|
1420
1952
|
|
|
1421
1953
|
// src/cli.ts
|
|
1422
1954
|
var STATELESS_HANDLERS = {
|
|
1423
|
-
"open-browser":
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
"
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
"
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
"
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
"
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
"get-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
"
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
"
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1955
|
+
"open-browser": {
|
|
1956
|
+
fn: browserHandlers.openBrowser,
|
|
1957
|
+
description: "Open the browser, both environment and profile mean browser"
|
|
1958
|
+
},
|
|
1959
|
+
"close-browser": {
|
|
1960
|
+
fn: browserHandlers.closeBrowser,
|
|
1961
|
+
description: "Close the browser"
|
|
1962
|
+
},
|
|
1963
|
+
"create-browser": {
|
|
1964
|
+
fn: browserHandlers.createBrowser,
|
|
1965
|
+
description: "Create a browser"
|
|
1966
|
+
},
|
|
1967
|
+
"update-browser": {
|
|
1968
|
+
fn: browserHandlers.updateBrowser,
|
|
1969
|
+
description: "Update the browser"
|
|
1970
|
+
},
|
|
1971
|
+
"delete-browser": {
|
|
1972
|
+
fn: browserHandlers.deleteBrowser,
|
|
1973
|
+
description: "Delete the browser"
|
|
1974
|
+
},
|
|
1975
|
+
"get-browser-list": {
|
|
1976
|
+
fn: browserHandlers.getBrowserList,
|
|
1977
|
+
description: "Get the list of browsers"
|
|
1978
|
+
},
|
|
1979
|
+
"get-opened-browser": {
|
|
1980
|
+
fn: browserHandlers.getOpenedBrowser,
|
|
1981
|
+
description: "Get the list of opened browsers"
|
|
1982
|
+
},
|
|
1983
|
+
"move-browser": {
|
|
1984
|
+
fn: browserHandlers.moveBrowser,
|
|
1985
|
+
description: "Move browsers to a group"
|
|
1986
|
+
},
|
|
1987
|
+
"get-profile-cookies": {
|
|
1988
|
+
fn: browserHandlers.getProfileCookies,
|
|
1989
|
+
description: "Query and return cookies of the specified profile. Only one profile can be queried per request."
|
|
1990
|
+
},
|
|
1991
|
+
"get-profile-ua": {
|
|
1992
|
+
fn: browserHandlers.getProfileUa,
|
|
1993
|
+
description: "Query and return the User-Agent of specified profiles. Up to 10 profiles can be queried per request."
|
|
1994
|
+
},
|
|
1995
|
+
"close-all-profiles": {
|
|
1996
|
+
fn: browserHandlers.closeAllProfiles,
|
|
1997
|
+
description: "Close all opened profiles on the current device"
|
|
1998
|
+
},
|
|
1999
|
+
"new-fingerprint": {
|
|
2000
|
+
fn: browserHandlers.newFingerprint,
|
|
2001
|
+
description: "Generate a new fingerprint for specified profiles. Up to 10 profiles are supported per request."
|
|
2002
|
+
},
|
|
2003
|
+
"delete-cache-v2": {
|
|
2004
|
+
fn: browserHandlers.deleteCacheV2,
|
|
2005
|
+
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."
|
|
2006
|
+
},
|
|
2007
|
+
"share-profile": {
|
|
2008
|
+
fn: browserHandlers.shareProfile,
|
|
2009
|
+
description: "Share profiles via account email or phone number. The maximum number of profiles that can be shared at one time is 200."
|
|
2010
|
+
},
|
|
2011
|
+
"get-browser-active": {
|
|
2012
|
+
fn: browserHandlers.getBrowserActive,
|
|
2013
|
+
description: "Get active browser profile information"
|
|
2014
|
+
},
|
|
2015
|
+
"get-cloud-active": {
|
|
2016
|
+
fn: browserHandlers.getCloudActive,
|
|
2017
|
+
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."'
|
|
2018
|
+
},
|
|
2019
|
+
"create-group": {
|
|
2020
|
+
fn: groupHandlers.createGroup,
|
|
2021
|
+
description: "Create a browser group"
|
|
2022
|
+
},
|
|
2023
|
+
"update-group": {
|
|
2024
|
+
fn: groupHandlers.updateGroup,
|
|
2025
|
+
description: "Update the browser group"
|
|
2026
|
+
},
|
|
2027
|
+
"get-group-list": {
|
|
2028
|
+
fn: groupHandlers.getGroupList,
|
|
2029
|
+
description: "Get the list of groups"
|
|
2030
|
+
},
|
|
2031
|
+
"check-status": {
|
|
2032
|
+
fn: applicationHandlers.checkStatus,
|
|
2033
|
+
description: "Check the availability of the current device API interface (Connection Status)"
|
|
2034
|
+
},
|
|
2035
|
+
"get-application-list": {
|
|
2036
|
+
fn: applicationHandlers.getApplicationList,
|
|
2037
|
+
description: "Get the list of applications (categories)"
|
|
2038
|
+
},
|
|
2039
|
+
"create-proxy": {
|
|
2040
|
+
fn: proxyHandlers.createProxy,
|
|
2041
|
+
description: "Create the proxy"
|
|
2042
|
+
},
|
|
2043
|
+
"update-proxy": {
|
|
2044
|
+
fn: proxyHandlers.updateProxy,
|
|
2045
|
+
description: "Update the proxy"
|
|
2046
|
+
},
|
|
2047
|
+
"get-proxy-list": {
|
|
2048
|
+
fn: proxyHandlers.getProxyList,
|
|
2049
|
+
description: "Get the list of proxies"
|
|
2050
|
+
},
|
|
2051
|
+
"delete-proxy": {
|
|
2052
|
+
fn: proxyHandlers.deleteProxy,
|
|
2053
|
+
description: "Delete the proxy"
|
|
2054
|
+
},
|
|
2055
|
+
"get-tag-list": {
|
|
2056
|
+
fn: tagHandlers.getTagList,
|
|
2057
|
+
description: "Get the list of browser tags"
|
|
2058
|
+
},
|
|
2059
|
+
"create-tag": {
|
|
2060
|
+
fn: tagHandlers.createTag,
|
|
2061
|
+
description: "Create browser tags (batch supported)"
|
|
2062
|
+
},
|
|
2063
|
+
"update-tag": {
|
|
2064
|
+
fn: tagHandlers.updateTag,
|
|
2065
|
+
description: "Update browser tags (batch supported)"
|
|
2066
|
+
},
|
|
2067
|
+
"delete-tag": {
|
|
2068
|
+
fn: tagHandlers.deleteTag,
|
|
2069
|
+
description: "Delete browser tags"
|
|
2070
|
+
},
|
|
2071
|
+
"download-kernel": {
|
|
2072
|
+
fn: kernelHandlers.downloadKernel,
|
|
2073
|
+
description: "Download or update a browser kernel version"
|
|
2074
|
+
},
|
|
2075
|
+
"get-kernel-list": {
|
|
2076
|
+
fn: kernelHandlers.getKernelList,
|
|
2077
|
+
description: "Get browser kernel list by type or all"
|
|
2078
|
+
},
|
|
2079
|
+
"update-patch": {
|
|
2080
|
+
fn: patchHandlers.updatePatch,
|
|
2081
|
+
description: "Update AdsPower to latest patch version"
|
|
2082
|
+
}
|
|
1455
2083
|
};
|
|
1456
2084
|
var SINGLE_PROFILE_ID_COMMANDS = {
|
|
1457
2085
|
"open-browser": "profileId",
|
|
@@ -1460,56 +2088,109 @@ var SINGLE_PROFILE_ID_COMMANDS = {
|
|
|
1460
2088
|
"get-browser-active": "profileId"
|
|
1461
2089
|
};
|
|
1462
2090
|
var SINGLE_PROFILE_ID_ARRAY_COMMANDS = ["get-profile-ua", "new-fingerprint"];
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
if (
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
2091
|
+
|
|
2092
|
+
// src/index.ts
|
|
2093
|
+
var program = new import_commander.Command();
|
|
2094
|
+
program.name("adspower-browser").description("CLI and runtime for adspower-browser").version(VERSION);
|
|
2095
|
+
program.command("start").description("Start the adspower runtime").option("-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) => {
|
|
2096
|
+
if (options.apiKey) {
|
|
2097
|
+
store.setStoreValue("apiKey", options.apiKey);
|
|
2098
|
+
} else {
|
|
2099
|
+
const apiKey = process.env.ADS_API_KEY;
|
|
2100
|
+
if (!apiKey) {
|
|
2101
|
+
logError("error: required option '-k, --api-key <apiKey>' not specified");
|
|
2102
|
+
process.exit(1);
|
|
2103
|
+
}
|
|
2104
|
+
store.setStoreValue("apiKey", "");
|
|
2105
|
+
}
|
|
2106
|
+
if (options.baseUrl) {
|
|
2107
|
+
store.setStoreValue("baseUrl", options.baseUrl);
|
|
2108
|
+
}
|
|
2109
|
+
if (options.nodeEnv) {
|
|
2110
|
+
store.setStoreValue("nodeEnv", options.nodeEnv);
|
|
2111
|
+
}
|
|
2112
|
+
await startChild();
|
|
2113
|
+
});
|
|
2114
|
+
program.command("stop").description("Stop the adspower runtime").action(async () => {
|
|
2115
|
+
await stopChild();
|
|
2116
|
+
});
|
|
2117
|
+
program.command("restart").description("Restart the adspower runtime").action(async () => {
|
|
2118
|
+
await restartChild();
|
|
2119
|
+
});
|
|
2120
|
+
program.command("status").description("Get the status of the adspower runtime").action(async () => {
|
|
2121
|
+
getChildStatus();
|
|
2122
|
+
});
|
|
2123
|
+
for (const cmd of Object.keys(STATELESS_HANDLERS)) {
|
|
2124
|
+
const fnc = STATELESS_HANDLERS[cmd].fn;
|
|
2125
|
+
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) => {
|
|
2126
|
+
const isRun = await hasRunning(options);
|
|
2127
|
+
if (!isRun) {
|
|
2128
|
+
logError("[!] Adspower runtime is not running");
|
|
2129
|
+
const info = `[i] Please run "${(0, import_colors2.green)("adspower-browser start -k <apiKey>")}" to start the adspower runtime`;
|
|
2130
|
+
console.log(info);
|
|
2131
|
+
return;
|
|
2132
|
+
}
|
|
2133
|
+
const { apiKey, port } = getApiKeyAndPort(options);
|
|
2134
|
+
updateConfig(apiKey, port);
|
|
2135
|
+
let args = {};
|
|
2136
|
+
if (params) {
|
|
2137
|
+
const trimmed = params.trim();
|
|
2138
|
+
if (trimmed.startsWith("{")) {
|
|
2139
|
+
try {
|
|
2140
|
+
args = JSON.parse(params);
|
|
2141
|
+
} catch {
|
|
2142
|
+
logError("Invalid JSON for command args");
|
|
2143
|
+
return;
|
|
2144
|
+
}
|
|
2145
|
+
} else if (SINGLE_PROFILE_ID_COMMANDS[command.name()]) {
|
|
2146
|
+
const key = SINGLE_PROFILE_ID_COMMANDS[command.name()];
|
|
2147
|
+
if (!isNaN(Number(trimmed))) {
|
|
2148
|
+
args = { profileNo: Number(trimmed) };
|
|
2149
|
+
} else {
|
|
2150
|
+
args = { profileId: trimmed };
|
|
2151
|
+
}
|
|
2152
|
+
} else if (SINGLE_PROFILE_ID_ARRAY_COMMANDS.includes(command.name())) {
|
|
2153
|
+
args = { profileId: [trimmed] };
|
|
2154
|
+
} else {
|
|
2155
|
+
try {
|
|
2156
|
+
args = JSON.parse(params);
|
|
2157
|
+
} catch {
|
|
2158
|
+
logError(`Command requires JSON args (e.g. '{"key":"value"}') or use a supported shorthand`);
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
1485
2161
|
}
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
2162
|
+
}
|
|
2163
|
+
logSuccess(`Executing command: ${command.name()}, params: ${JSON.stringify(args)}`);
|
|
2164
|
+
const loading = createLoading(`Executing ${command.name()}...`);
|
|
2165
|
+
try {
|
|
2166
|
+
if (command.name() === "download-kernel") {
|
|
2167
|
+
loading.stop();
|
|
2168
|
+
const result = await trackKernelDownload(fnc, args);
|
|
2169
|
+
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
2170
|
+
logInfo(`
|
|
2171
|
+
|
|
2172
|
+
${out}
|
|
2173
|
+
|
|
2174
|
+
`);
|
|
2175
|
+
} else {
|
|
2176
|
+
const result = await fnc(args);
|
|
2177
|
+
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
2178
|
+
logInfo(`
|
|
2179
|
+
|
|
2180
|
+
${out}
|
|
2181
|
+
`);
|
|
2182
|
+
if (command.name() === "update-patch" && !out.includes("The client is already on the latest patch version. No update is required")) {
|
|
2183
|
+
loading.stop();
|
|
2184
|
+
await sleepTime(1e3 * 60);
|
|
2185
|
+
await restartChild();
|
|
2186
|
+
}
|
|
1496
2187
|
}
|
|
2188
|
+
} finally {
|
|
2189
|
+
loading.stop();
|
|
1497
2190
|
}
|
|
1498
|
-
}
|
|
1499
|
-
return { command, args };
|
|
1500
|
-
}
|
|
1501
|
-
async function main() {
|
|
1502
|
-
const argv = process.argv.slice(2);
|
|
1503
|
-
try {
|
|
1504
|
-
const { command, args } = parseArgv(argv);
|
|
1505
|
-
const handler = STATELESS_HANDLERS[command];
|
|
1506
|
-
const result = await handler(args);
|
|
1507
|
-
const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
1508
|
-
process.stdout.write(out + "\n");
|
|
1509
|
-
} catch (err) {
|
|
1510
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1511
|
-
process.stderr.write(msg + "\n");
|
|
1512
|
-
process.exit(1);
|
|
1513
|
-
}
|
|
2191
|
+
});
|
|
1514
2192
|
}
|
|
1515
|
-
|
|
2193
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
2194
|
+
console.error(error);
|
|
2195
|
+
process.exit(1);
|
|
2196
|
+
});
|