adspower-browser 2.0.6 → 2.0.7

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.
Files changed (2) hide show
  1. package/cli/index.js +510 -315
  2. package/package.json +1 -1
package/cli/index.js CHANGED
@@ -93,11 +93,12 @@ var Store = class {
93
93
  var store = new Store();
94
94
 
95
95
  // src/core/start.ts
96
- var fs2 = __toESM(require("fs"));
97
- var path2 = __toESM(require("path"));
98
- var import_node_child_process2 = require("child_process");
96
+ var fs3 = __toESM(require("fs"));
97
+ var path4 = __toESM(require("path"));
98
+ var import_node_child_process3 = require("child_process");
99
99
 
100
100
  // src/tools/index.ts
101
+ var readline = __toESM(require("readline/promises"));
101
102
  var os = __toESM(require("os"));
102
103
  var path = __toESM(require("path"));
103
104
  var fs = __toESM(require("fs"));
@@ -288,244 +289,188 @@ var initSqlite3 = () => {
288
289
  logSuccess(`[i] SQLite file initialized successfully!`);
289
290
  }
290
291
  };
291
-
292
- // src/core/start.ts
293
- var getRuntimeExecArgv = () => {
294
- if (process.platform !== "win32") {
295
- return [];
292
+ async function promptYesNo(question) {
293
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
294
+ logWarning("[!] Interactive prompt is unavailable in non-interactive mode.");
295
+ return null;
296
296
  }
297
- const preload = path2.join(__dirname, "core/winHideChildProcess.js");
298
- if (!fs2.existsSync(preload)) {
299
- return [];
297
+ const rl = readline.createInterface({
298
+ input: process.stdin,
299
+ output: process.stdout
300
+ });
301
+ try {
302
+ while (true) {
303
+ const answer = (await rl.question(`${question} [y/N]: `)).trim().toLowerCase();
304
+ if (answer === "y" || answer === "yes") {
305
+ return "y";
306
+ }
307
+ if (answer === "n" || answer === "no" || answer === "") {
308
+ return "n";
309
+ }
310
+ logWarning("[!] Please enter y or n.");
311
+ }
312
+ } finally {
313
+ rl.close();
300
314
  }
301
- return ["--require", preload];
302
- };
303
- var getEnv = () => {
304
- const env = {
305
- ...process.env,
306
- // 系统的环境变量信息
307
- API_KEY: store.getStoreValue("apiKey"),
308
- IS_CLOUD_BROWSER: true
309
- // 云浏览器场景预留标识
315
+ }
316
+
317
+ // src/core/check.ts
318
+ var import_axios = __toESM(require("axios"));
319
+ var import_fs = __toESM(require("fs"));
320
+ var import_path = __toESM(require("path"));
321
+ var import_node_child_process2 = require("child_process");
322
+ var NPM_PACKAGE_NAME = "adspower-browser";
323
+ var NPM_REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE_NAME}/latest`;
324
+ var checkUpdates = async (apiKey, baseUrl) => {
325
+ const [js, npm] = await Promise.all([
326
+ checkUpdateJS(apiKey, baseUrl),
327
+ checkUpdateNpmPackage()
328
+ ]);
329
+ return {
330
+ js,
331
+ npm: npm.hasUpdate,
332
+ npmLatestVersion: npm.latestVersion
310
333
  };
311
- if (store.getStoreValue("baseUrl")) {
312
- env.BASE_URL = store.getStoreValue("baseUrl");
313
- }
314
- if (store.getStoreValue("nodeEnv")) {
315
- env.NODE_ENV = store.getStoreValue("nodeEnv");
316
- }
317
- return env;
318
334
  };
319
- var startChild = (type) => {
320
- let timer;
321
- let child = null;
322
- return new Promise(async (resolve, reject) => {
323
- initSqlite3();
324
- const processInstance = readPidFile();
325
- if (processInstance && processInstance.pid) {
326
- const isRun = await isRunning(processInstance.pid);
327
- removePidFile();
328
- if (isRun) {
329
- process.kill(Number(processInstance.pid), "SIGKILL");
330
- await sleepTime(1e3);
331
- }
335
+ var checkUpdateJS = async (apiKey, baseUrl) => {
336
+ return new Promise(async (resolve) => {
337
+ let system = "";
338
+ if (process.platform === "win32") {
339
+ system = process.arch === "x64" ? "x64" : "x86";
332
340
  }
333
- const env = Object.fromEntries(
334
- Object.entries(getEnv()).map(([key, value]) => [key, value == null ? value : String(value)])
335
- );
336
- try {
337
- const mainJs = path2.join(__dirname, "../cwd/lib", "main.min.js");
338
- const forkOptions = {
339
- env,
340
- detached: true,
341
- windowsHide: true,
342
- // 隐藏子进程的控制台窗口
343
- stdio: ["ignore", "ignore", "ignore", "ipc"],
344
- execArgv: getRuntimeExecArgv()
345
- };
346
- child = (0, import_node_child_process2.fork)(mainJs, [], forkOptions);
347
- ensureBrowserPath();
348
- store.setStoreValue("status", "starting");
349
- logSuccess(`[i] Adspower program is starting...`);
350
- store.setStoreValue("pid", child?.pid?.toString() || "");
351
- let isAppPortOk = false;
352
- writePidFile(store.getAllStoreValue());
353
- child.on("message", async (msg) => {
354
- const text = String(msg);
355
- if (text.indexOf("SERVER_PORT_$$_") === 0 && !isAppPortOk) {
356
- const port = text.replace("SERVER_PORT_$$_", "").trim();
357
- store.setStoreValue("appPort", port);
358
- isAppPortOk = true;
359
- }
360
- if (text.indexOf("START_API_SERVER_SUCCESS_$$_") === 0) {
361
- const port = text.replace("START_API_SERVER_SUCCESS_$$_", "").trim();
362
- store.setStoreValue("apiPort", port);
363
- const localUrl = `http://local.adspower.net:${port}`;
364
- logSuccess(`Server running at:`);
365
- logSuccess(` - local: ${toTerminalLink(localUrl)}`);
366
- writePidFile(store.getAllStoreValue());
367
- if (child) {
368
- child.disconnect();
369
- child.unref();
370
- }
371
- }
372
- if (text.includes("CACHE_FOLDER_$$_")) {
373
- const cacheFolder = text.replace("CACHE_FOLDER_$$_", "").trim();
374
- logSuccess(`[i] Cache folder: ${cacheFolder}`);
375
- }
376
- if (text.indexOf("START_API_SERVER_FAIL_$$_") === 0) {
377
- const serverMsg = text.replace("START_API_SERVER_FAIL_$$_", "").split("_").filter(Boolean);
378
- if (serverMsg[0]) {
379
- logError(`ERROR - ${serverMsg[0]}`);
380
- }
381
- if (serverMsg[1]) {
382
- logError(`ERROR - ${serverMsg[1]}`);
383
- }
384
- process.exit(0);
385
- }
386
- if (text === "start") {
387
- clearTimeout(timer);
388
- resolve();
389
- store.setStoreValue("status", "doing");
390
- writePidFile(store.getAllStoreValue());
391
- }
392
- if (text === "restart") {
393
- child && child.kill("SIGKILL");
394
- store.setStoreValue("status", "restarting");
395
- startChild("2").catch(() => {
396
- });
397
- }
398
- if (text.indexOf("INTRANET_$$_") > -1) {
399
- const arr = text.split("_$$_");
400
- if (arr && arr[1]) {
401
- store.setStoreValue("intranet", arr[1]);
341
+ if (process.platform === "darwin") {
342
+ system = process.arch === "arm64" ? "arm64" : "mac";
343
+ }
344
+ if (process.platform === "linux") {
345
+ system = "linux_x64";
346
+ }
347
+ const curVersion = await getCurVersion();
348
+ if (!curVersion) {
349
+ resolve(false);
350
+ return;
351
+ }
352
+ import_axios.default.get(`${baseUrl || "https://api.adspower.com/"}client/sys-version/list`, {
353
+ headers: {
354
+ "api-key": apiKey
355
+ },
356
+ params: {
357
+ version: `v${curVersion}`,
358
+ system
359
+ }
360
+ }).then(async (res) => {
361
+ const data = res.data.data;
362
+ if (data && data.js) {
363
+ const newVersion = data.js.version;
364
+ if (curVersion) {
365
+ if (greaterThanVersion(newVersion, curVersion)) {
366
+ resolve(true);
367
+ return;
402
368
  }
403
369
  }
404
- if (text === "browser-kill") {
405
- await browsersKill();
406
- }
407
- if (text.indexOf("RPA_PROCESS_PID_") > -1) {
408
- const rpaPid = text.replace("RPA_PROCESS_PID_", "");
409
- store.setStoreValue("rpaPid", rpaPid);
410
- }
411
- if (text.indexOf("RPA_PLUS_PROCESS_PID_") > -1) {
412
- const rpaPlusPid = text.replace("RPA_PLUS_PROCESS_PID_", "");
413
- store.setStoreValue("rpaPlusPid", rpaPlusPid);
414
- }
415
- if (text.indexOf("AI_PROCESS_PID_") > -1) {
416
- const aiPid = text.replace("AI_PROCESS_PID_", "");
417
- store.setStoreValue("aiPid", aiPid);
418
- }
419
- });
420
- child.on("error", (err) => {
421
- logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${err.message}`);
422
- store.setStoreValue("status", "stop");
423
- store.clear();
424
- removePidFile();
425
- process.exit(0);
426
- });
427
- child.on("exit", async (code, signal) => {
428
- if (signal === "SIGKILL") {
429
- await browsersKill();
430
- store.clear();
431
- removePidFile();
432
- } else {
433
- child = null;
434
- await sleepTime(500);
435
- startChild("2").then(() => {
436
- }).catch(() => {
437
- logError("[!] Restart failed");
438
- });
439
- }
440
- });
441
- timer = setTimeout(() => {
442
- child && child.kill("SIGKILL");
443
- child = null;
444
- store.setStoreValue("status", "stop");
445
- logError("[!] Start Timeout");
446
- reject("Start Timeout");
447
- }, 30 * 1e3);
448
- } catch (error) {
449
- clearTimeout(timer);
450
- reject(error);
451
- child = null;
452
- store.clear();
453
- logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
454
- }
370
+ }
371
+ resolve(false);
372
+ }).catch((err) => {
373
+ console.log(err);
374
+ resolve(false);
375
+ });
455
376
  });
456
377
  };
457
- var stopChild = async () => {
458
- const processInstance = readPidFile();
459
- if (processInstance.pid) {
460
- const isRun = await isRunning(processInstance.pid);
461
- try {
462
- process.kill(Number(processInstance.pid), "SIGKILL");
463
- removePidFile();
464
- } catch (error) {
465
- try {
466
- await sleepTime(2e3);
467
- process.kill(Number(processInstance.pid), "SIGKILL");
468
- removePidFile();
469
- } catch (error2) {
470
- logError(`[!] Stop child fail: ${error2 instanceof Error ? error2.message : JSON.stringify(error2)}`);
471
- if (isRun) {
472
- logWarning(`[!] Please manually close the browser process: ${processInstance.pid}`);
473
- }
474
- return;
475
- }
378
+ var checkUpdateNpmPackage = async () => {
379
+ try {
380
+ const res = await import_axios.default.get(NPM_REGISTRY_URL, {
381
+ timeout: 3e4
382
+ });
383
+ const latestVersion = res.data?.version;
384
+ if (!latestVersion || typeof latestVersion !== "string") {
385
+ return { hasUpdate: false };
476
386
  }
477
- logSuccess("[i] Adspower program is stopped");
478
- } else {
479
- logInfo("[i] No running adspower program");
387
+ return {
388
+ hasUpdate: greaterThanVersion(latestVersion, VERSION),
389
+ latestVersion
390
+ };
391
+ } catch (err) {
392
+ return { hasUpdate: false };
480
393
  }
481
394
  };
482
- var restartChild = async () => {
483
- const processInstance = readPidFile();
484
- if (processInstance.pid) {
485
- const apiKey = processInstance.apiKey;
486
- const baseUrl = processInstance.baseUrl;
487
- const nodeEnv = processInstance.nodeEnv;
488
- await stopChild();
489
- await sleepTime(1e3);
490
- store.setStoreValue("apiKey", apiKey);
491
- store.setStoreValue("baseUrl", baseUrl);
492
- store.setStoreValue("nodeEnv", nodeEnv);
493
- await startChild().then(() => {
494
- logSuccess("[i] Adspower program is restarted");
495
- }).catch((error) => {
496
- logError(`[!] Restart failed: ${error.message}`);
395
+ var updateNpmPackage = async () => {
396
+ const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
397
+ await new Promise((resolve, reject) => {
398
+ const child = (0, import_node_child_process2.spawn)(npmCommand, ["install", "-g", `${NPM_PACKAGE_NAME}@latest`], {
399
+ stdio: "inherit",
400
+ windowsHide: true
497
401
  });
498
- } else {
499
- logInfo("[i] No running adspower program");
402
+ child.on("error", reject);
403
+ child.on("close", (code) => {
404
+ if (code === 0) {
405
+ resolve();
406
+ return;
407
+ }
408
+ reject(new Error(`npm install exited with code ${code}`));
409
+ });
410
+ });
411
+ };
412
+ var getCurVersion = async () => {
413
+ const mainJs = import_path.default.join(__dirname, "../cwd/lib", "main.min.js");
414
+ const curVersion = getVersion(await readFirstLienVersion(mainJs, (msg) => {
415
+ }));
416
+ return curVersion;
417
+ };
418
+ var getVersion = (line) => {
419
+ if (!line) {
420
+ return "";
500
421
  }
422
+ return line.split(/\D/).filter((e) => e).join(".");
501
423
  };
502
- var getChildStatus = async () => {
503
- const processInstance = readPidFile();
504
- if (processInstance.pid) {
505
- const isRun = await isRunning(processInstance.pid);
506
- if (!isRun) {
507
- removePidFile();
508
- logInfo("[i] Adspower program is not running");
424
+ var readFirstLienVersion = (filePath, cb) => new Promise((resolve) => {
425
+ const rs = import_fs.default.createReadStream(filePath, {
426
+ encoding: "utf8",
427
+ start: 0,
428
+ end: 30
429
+ });
430
+ let acc = "";
431
+ let pos = 0;
432
+ let index;
433
+ rs.on("data", (chunk) => {
434
+ index = chunk.indexOf("\n");
435
+ acc += chunk;
436
+ index !== -1 ? rs.close() : pos += chunk.length;
437
+ }).on("close", () => {
438
+ const line = acc.slice(0, pos + index);
439
+ const i = line.indexOf("AdsPower") !== -1 ? line.indexOf("AdsPower") : line.indexOf("RPA");
440
+ if (i > 0 && i < 50) {
441
+ cb(`line-${line}`);
442
+ resolve(line);
509
443
  return;
510
444
  }
511
- const status = processInstance.status;
512
- if (status === "starting") {
513
- logSuccess("[i] Adspower program is starting...");
514
- } else if (status === "doing" && processInstance.apiPort) {
515
- logSuccess("[i] Adspower program is running at:");
516
- logSuccess(` - http://local.adspower.net:${processInstance.apiPort}`);
517
- } else if (status === "stop") {
518
- logInfo("[i] Adspower program is stopped");
519
- } else {
520
- logInfo("[i] Adspower program is not started");
445
+ resolve("");
446
+ }).on("error", (err) => {
447
+ resolve("");
448
+ });
449
+ });
450
+ var greaterThanVersion = (onlineVersion, localVersion) => {
451
+ if (!onlineVersion) {
452
+ return false;
453
+ }
454
+ if (!localVersion) {
455
+ return false;
456
+ }
457
+ const onlineTemp = onlineVersion.replace(/[a-zA-Z]/g, "");
458
+ const localTemp = localVersion.replace(/[a-zA-Z]/g, "");
459
+ if (onlineTemp === localTemp) {
460
+ return false;
461
+ }
462
+ const onlineArr = onlineTemp.split(".");
463
+ const localArr = localTemp.split(".");
464
+ for (let i = 0; i < onlineArr.length; i += 1) {
465
+ if (+onlineArr[i] !== +localArr[i]) {
466
+ return +onlineArr[i] > +localArr[i];
521
467
  }
522
- } else {
523
- logInfo("[i] Adspower program is not running");
524
468
  }
469
+ return false;
525
470
  };
526
471
 
527
472
  // ../core/src/constants/api.ts
528
- var import_axios = __toESM(require("axios"));
473
+ var import_axios2 = __toESM(require("axios"));
529
474
 
530
475
  // ../core/src/constants/config.ts
531
476
  function parseArgs() {
@@ -962,11 +907,11 @@ var API_ENDPOINTS = {
962
907
  GET_KERNEL_LIST: LOCAL_API_CONTRACTS["get-kernel-list"].path,
963
908
  UPDATE_PATCH: LOCAL_API_CONTRACTS["update-patch"].path
964
909
  };
965
- var apiClient = import_axios.default.create({
910
+ var apiClient = import_axios2.default.create({
966
911
  headers: API_KEY ? { "Authorization": `Bearer ${API_KEY}` } : {}
967
912
  });
968
913
  var getApiClient = () => {
969
- const client = import_axios.default.create({
914
+ const client = import_axios2.default.create({
970
915
  headers: CONFIG.apiKey ? { "Authorization": `Bearer ${CONFIG.apiKey}` } : {}
971
916
  });
972
917
  client.interceptors.request.use(async (config2) => {
@@ -1652,7 +1597,7 @@ var tagHandlers = {
1652
1597
  };
1653
1598
 
1654
1599
  // ../core/src/handlers/automation.ts
1655
- var import_path = __toESM(require("path"));
1600
+ var import_path2 = __toESM(require("path"));
1656
1601
  var import_os = __toESM(require("os"));
1657
1602
 
1658
1603
  // ../core/src/utils/browserBase.ts
@@ -1706,7 +1651,7 @@ var BrowserBase = class {
1706
1651
  var browserBase_default = new BrowserBase();
1707
1652
 
1708
1653
  // ../core/src/handlers/automation.ts
1709
- var defaultDownloadsPath = import_path.default.join(import_os.default.homedir(), "Downloads");
1654
+ var defaultDownloadsPath = import_path2.default.join(import_os.default.homedir(), "Downloads");
1710
1655
 
1711
1656
  // ../core/src/handlers/kernel.ts
1712
1657
  var kernelHandlers = {
@@ -2504,6 +2449,9 @@ var schemas = {
2504
2449
  }).strict()
2505
2450
  };
2506
2451
 
2452
+ // src/handleAction.ts
2453
+ var import_colors2 = require("colors");
2454
+
2507
2455
  // src/cli.ts
2508
2456
  function formatJsonValueForHelp(value, indent) {
2509
2457
  const pad = " ".repeat(indent);
@@ -2803,77 +2751,7 @@ function resolveStatelessCommandArgs(commandName, params) {
2803
2751
  }
2804
2752
  }
2805
2753
 
2806
- // src/startConfig.ts
2807
- var MISSING_API_KEY_ERROR = "error: required option '-k, --api-key <apiKey>' not specified";
2808
- function resolveStartApiKey(optionApiKey, env = process.env) {
2809
- if (optionApiKey) {
2810
- return {
2811
- ok: true,
2812
- apiKey: optionApiKey
2813
- };
2814
- }
2815
- if (env.ADS_API_KEY) {
2816
- return {
2817
- ok: true,
2818
- apiKey: env.ADS_API_KEY
2819
- };
2820
- }
2821
- return {
2822
- ok: false,
2823
- error: MISSING_API_KEY_ERROR
2824
- };
2825
- }
2826
-
2827
- // src/completion.ts
2828
- var import_commander = __toESM(require("@bomb.sh/tab/commander"));
2829
- var CLI_BIN_ALIASES = ["ads", "adspower", "adspower-browser"];
2830
- function patchShellCompletionScript(shell, script) {
2831
- if (shell === "zsh") {
2832
- return script.replace(/^#compdef .+$/m, `#compdef ${CLI_BIN_ALIASES.join(" ")}`).replace(/^compdef _ads ads$/m, `compdef _ads ${CLI_BIN_ALIASES.join(" ")}`);
2833
- }
2834
- if (shell === "bash") {
2835
- return script.replace(
2836
- /^complete -F __ads_complete ads$/m,
2837
- `complete -F __ads_complete ${CLI_BIN_ALIASES.join(" ")}`
2838
- );
2839
- }
2840
- return script;
2841
- }
2842
- function setupShellCompletion(program2) {
2843
- program2.name("ads");
2844
- (0, import_commander.default)(program2);
2845
- }
2846
- function isShellCompletionRequest(argv = process.argv) {
2847
- const completionIndex = argv.indexOf("complete");
2848
- const dashDashIndex = argv.indexOf("--");
2849
- return completionIndex !== -1 && dashDashIndex !== -1 && dashDashIndex > completionIndex;
2850
- }
2851
- function wrapShellScriptOutput(shell) {
2852
- if (shell !== "zsh" && shell !== "bash") {
2853
- return () => {
2854
- };
2855
- }
2856
- const originalWrite = process.stdout.write.bind(process.stdout);
2857
- process.stdout.write = ((chunk, encoding, callback) => {
2858
- const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString(typeof encoding === "string" ? encoding : "utf8");
2859
- const patched = patchShellCompletionScript(shell, text);
2860
- if (typeof encoding === "function") {
2861
- return originalWrite(patched, encoding);
2862
- }
2863
- return originalWrite(
2864
- patched,
2865
- encoding,
2866
- callback
2867
- );
2868
- });
2869
- return () => {
2870
- process.stdout.write = originalWrite;
2871
- };
2872
- }
2873
-
2874
2754
  // src/handleAction.ts
2875
- var readline = __toESM(require("readline/promises"));
2876
- var import_colors2 = require("colors");
2877
2755
  var renderKernelProgress = (result) => {
2878
2756
  const status = result.status || "pending";
2879
2757
  const progress = ["completed", "installing"].includes(status) ? 100 : Math.max(0, Math.min(100, Number(result.progress) || 0));
@@ -2940,6 +2818,21 @@ var handleAction = async (params, options, command, fnc) => {
2940
2818
  ${out}
2941
2819
 
2942
2820
  `);
2821
+ } else if (commandName === "update-patch") {
2822
+ const result = await fnc(args);
2823
+ const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
2824
+ if (!out.includes("The client is already on the latest patch version. No update is required")) {
2825
+ await sleepTime(1e3 * 60);
2826
+ loading.stop();
2827
+ await restartChild();
2828
+ } else {
2829
+ loading.stop();
2830
+ }
2831
+ logInfo(`
2832
+
2833
+ ${out}
2834
+ `);
2835
+ return out;
2943
2836
  } else {
2944
2837
  const result = await fnc(args);
2945
2838
  const out = typeof result === "string" ? result : JSON.stringify(result, null, 2);
@@ -2948,10 +2841,6 @@ ${out}
2948
2841
 
2949
2842
  ${out}
2950
2843
  `);
2951
- if (commandName === "update-patch" && !out.includes("The client is already on the latest patch version. No update is required")) {
2952
- await sleepTime(1e3 * 60);
2953
- await restartChild();
2954
- }
2955
2844
  return out;
2956
2845
  }
2957
2846
  } catch (error) {
@@ -3031,29 +2920,335 @@ var handleError = async (msg, commandName, params) => {
3031
2920
  }
3032
2921
  }
3033
2922
  };
3034
- async function promptYesNo(question) {
3035
- if (!process.stdin.isTTY || !process.stdout.isTTY) {
3036
- logWarning("[!] Interactive prompt is unavailable in non-interactive mode.");
3037
- return null;
2923
+
2924
+ // src/core/start.ts
2925
+ var getRuntimeExecArgv = () => {
2926
+ if (process.platform !== "win32") {
2927
+ return [];
3038
2928
  }
3039
- const rl = readline.createInterface({
3040
- input: process.stdin,
3041
- output: process.stdout
3042
- });
3043
- try {
3044
- while (true) {
3045
- const answer = (await rl.question(`${question} [y/N]: `)).trim().toLowerCase();
3046
- if (answer === "y" || answer === "yes") {
3047
- return "y";
2929
+ const preload = path4.join(__dirname, "core/winHideChildProcess.js");
2930
+ if (!fs3.existsSync(preload)) {
2931
+ return [];
2932
+ }
2933
+ return ["--require", preload];
2934
+ };
2935
+ var getEnv = () => {
2936
+ const env = {
2937
+ ...process.env,
2938
+ // 系统的环境变量信息
2939
+ API_KEY: store.getStoreValue("apiKey"),
2940
+ IS_CLOUD_BROWSER: true
2941
+ // 云浏览器场景预留标识
2942
+ };
2943
+ if (store.getStoreValue("baseUrl")) {
2944
+ env.BASE_URL = store.getStoreValue("baseUrl");
2945
+ }
2946
+ if (store.getStoreValue("nodeEnv")) {
2947
+ env.NODE_ENV = store.getStoreValue("nodeEnv");
2948
+ }
2949
+ return env;
2950
+ };
2951
+ var startChild = (type) => {
2952
+ let timer;
2953
+ let child = null;
2954
+ return new Promise(async (resolve, reject) => {
2955
+ initSqlite3();
2956
+ const processInstance = readPidFile();
2957
+ if (processInstance && processInstance.pid) {
2958
+ const isRun = await isRunning(processInstance.pid);
2959
+ removePidFile();
2960
+ if (isRun) {
2961
+ process.kill(Number(processInstance.pid), "SIGKILL");
2962
+ await sleepTime(1e3);
3048
2963
  }
3049
- if (answer === "n" || answer === "no" || answer === "") {
3050
- return "n";
2964
+ }
2965
+ const env = Object.fromEntries(
2966
+ Object.entries(getEnv()).map(([key, value]) => [key, value == null ? value : String(value)])
2967
+ );
2968
+ try {
2969
+ const mainJs = path4.join(__dirname, "../cwd/lib", "main.min.js");
2970
+ const forkOptions = {
2971
+ env,
2972
+ detached: true,
2973
+ windowsHide: true,
2974
+ // 隐藏子进程的控制台窗口
2975
+ stdio: ["ignore", "ignore", "ignore", "ipc"],
2976
+ execArgv: getRuntimeExecArgv()
2977
+ };
2978
+ child = (0, import_node_child_process3.fork)(mainJs, [], forkOptions);
2979
+ ensureBrowserPath();
2980
+ store.setStoreValue("status", "starting");
2981
+ logSuccess(`[i] Adspower program is starting...`);
2982
+ store.setStoreValue("pid", child?.pid?.toString() || "");
2983
+ let isAppPortOk = false;
2984
+ writePidFile(store.getAllStoreValue());
2985
+ child.on("message", async (msg) => {
2986
+ const text = String(msg);
2987
+ if (text.indexOf("SERVER_PORT_$$_") === 0 && !isAppPortOk) {
2988
+ const port = text.replace("SERVER_PORT_$$_", "").trim();
2989
+ store.setStoreValue("appPort", port);
2990
+ isAppPortOk = true;
2991
+ }
2992
+ if (text.indexOf("START_API_SERVER_SUCCESS_$$_") === 0) {
2993
+ const port = text.replace("START_API_SERVER_SUCCESS_$$_", "").trim();
2994
+ store.setStoreValue("apiPort", port);
2995
+ writePidFile(store.getAllStoreValue());
2996
+ if (child) {
2997
+ child.disconnect();
2998
+ child.unref();
2999
+ }
3000
+ const updates = await checkUpdates(store.getStoreValue("apiKey"), store.getStoreValue("baseUrl"));
3001
+ if (updates.js || updates.npm) {
3002
+ const answer = await promptYesNo(`[?] A new update is available. Update now?`);
3003
+ if (answer === "y") {
3004
+ if (updates.npm) {
3005
+ try {
3006
+ logInfo(`[i] Updating adspower-browser npm package${updates.npmLatestVersion ? ` to ${updates.npmLatestVersion}` : ""}...`);
3007
+ await updateNpmPackage();
3008
+ logSuccess(`[i] adspower-browser npm package updated. Please use the next command execution for the new CLI version.`);
3009
+ if (!updates.js) {
3010
+ await restartChild();
3011
+ }
3012
+ } catch (error) {
3013
+ logWarning(`[!] Failed to update adspower-browser npm package: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
3014
+ }
3015
+ }
3016
+ if (updates.js) {
3017
+ await handleAction(
3018
+ JSON.stringify({ "version_type": "beta" }),
3019
+ {},
3020
+ { name: () => "update-patch" },
3021
+ STATELESS_HANDLERS["update-patch"].fn
3022
+ );
3023
+ }
3024
+ return;
3025
+ }
3026
+ }
3027
+ const localUrl = `http://local.adspower.net:${port}`;
3028
+ logSuccess(`Server running at:`);
3029
+ logSuccess(` - local: ${toTerminalLink(localUrl)}`);
3030
+ }
3031
+ if (text.includes("CACHE_FOLDER_$$_")) {
3032
+ const cacheFolder = text.replace("CACHE_FOLDER_$$_", "").trim();
3033
+ logSuccess(`[i] Cache folder: ${cacheFolder}`);
3034
+ }
3035
+ if (text.indexOf("START_API_SERVER_FAIL_$$_") === 0) {
3036
+ const serverMsg = text.replace("START_API_SERVER_FAIL_$$_", "").split("_").filter(Boolean);
3037
+ if (serverMsg[0]) {
3038
+ logError(`ERROR - ${serverMsg[0]}`);
3039
+ }
3040
+ if (serverMsg[1]) {
3041
+ logError(`ERROR - ${serverMsg[1]}`);
3042
+ }
3043
+ process.exit(0);
3044
+ }
3045
+ if (text === "start") {
3046
+ clearTimeout(timer);
3047
+ resolve();
3048
+ store.setStoreValue("status", "doing");
3049
+ writePidFile(store.getAllStoreValue());
3050
+ }
3051
+ if (text === "restart") {
3052
+ child && child.kill("SIGKILL");
3053
+ store.setStoreValue("status", "restarting");
3054
+ startChild("2").catch(() => {
3055
+ });
3056
+ }
3057
+ if (text.indexOf("INTRANET_$$_") > -1) {
3058
+ const arr = text.split("_$$_");
3059
+ if (arr && arr[1]) {
3060
+ store.setStoreValue("intranet", arr[1]);
3061
+ }
3062
+ }
3063
+ if (text === "browser-kill") {
3064
+ await browsersKill();
3065
+ }
3066
+ if (text.indexOf("RPA_PROCESS_PID_") > -1) {
3067
+ const rpaPid = text.replace("RPA_PROCESS_PID_", "");
3068
+ store.setStoreValue("rpaPid", rpaPid);
3069
+ }
3070
+ if (text.indexOf("RPA_PLUS_PROCESS_PID_") > -1) {
3071
+ const rpaPlusPid = text.replace("RPA_PLUS_PROCESS_PID_", "");
3072
+ store.setStoreValue("rpaPlusPid", rpaPlusPid);
3073
+ }
3074
+ if (text.indexOf("AI_PROCESS_PID_") > -1) {
3075
+ const aiPid = text.replace("AI_PROCESS_PID_", "");
3076
+ store.setStoreValue("aiPid", aiPid);
3077
+ }
3078
+ });
3079
+ child.on("error", (err) => {
3080
+ logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${err.message}`);
3081
+ store.setStoreValue("status", "stop");
3082
+ store.clear();
3083
+ removePidFile();
3084
+ process.exit(0);
3085
+ });
3086
+ child.on("exit", async (code, signal) => {
3087
+ if (signal === "SIGKILL") {
3088
+ await browsersKill();
3089
+ store.clear();
3090
+ removePidFile();
3091
+ } else {
3092
+ child = null;
3093
+ await sleepTime(500);
3094
+ startChild("2").then(() => {
3095
+ }).catch(() => {
3096
+ logError("[!] Restart failed");
3097
+ });
3098
+ }
3099
+ });
3100
+ timer = setTimeout(() => {
3101
+ child && child.kill("SIGKILL");
3102
+ child = null;
3103
+ store.setStoreValue("status", "stop");
3104
+ logError("[!] Start Timeout");
3105
+ reject("Start Timeout");
3106
+ }, 30 * 1e3);
3107
+ } catch (error) {
3108
+ clearTimeout(timer);
3109
+ reject(error);
3110
+ child = null;
3111
+ store.clear();
3112
+ logError(`[!] Node\u542F\u52A8\u5931\u8D25: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
3113
+ }
3114
+ });
3115
+ };
3116
+ var stopChild = async () => {
3117
+ const processInstance = readPidFile();
3118
+ if (processInstance.pid) {
3119
+ const isRun = await isRunning(processInstance.pid);
3120
+ try {
3121
+ process.kill(Number(processInstance.pid), "SIGKILL");
3122
+ removePidFile();
3123
+ } catch (error) {
3124
+ try {
3125
+ await sleepTime(2e3);
3126
+ process.kill(Number(processInstance.pid), "SIGKILL");
3127
+ removePidFile();
3128
+ } catch (error2) {
3129
+ logError(`[!] Stop child fail: ${error2 instanceof Error ? error2.message : JSON.stringify(error2)}`);
3130
+ if (isRun) {
3131
+ logWarning(`[!] Please manually close the browser process: ${processInstance.pid}`);
3132
+ }
3133
+ return;
3051
3134
  }
3052
- logWarning("[!] Please enter y or n.");
3053
3135
  }
3054
- } finally {
3055
- rl.close();
3136
+ logSuccess("[i] Adspower program is stopped");
3137
+ } else {
3138
+ logInfo("[i] No running adspower program");
3139
+ }
3140
+ };
3141
+ var restartChild = async () => {
3142
+ const processInstance = readPidFile();
3143
+ if (processInstance.pid) {
3144
+ const apiKey = processInstance.apiKey;
3145
+ const baseUrl = processInstance.baseUrl;
3146
+ const nodeEnv = processInstance.nodeEnv;
3147
+ await stopChild();
3148
+ await sleepTime(1e3);
3149
+ store.setStoreValue("apiKey", apiKey);
3150
+ store.setStoreValue("baseUrl", baseUrl);
3151
+ store.setStoreValue("nodeEnv", nodeEnv);
3152
+ await startChild().then(() => {
3153
+ logSuccess("[i] Adspower program is restarted");
3154
+ }).catch((error) => {
3155
+ logError(`[!] Restart failed: ${error.message}`);
3156
+ });
3157
+ } else {
3158
+ logInfo("[i] No running adspower program");
3056
3159
  }
3160
+ };
3161
+ var getChildStatus = async () => {
3162
+ const processInstance = readPidFile();
3163
+ if (processInstance.pid) {
3164
+ const isRun = await isRunning(processInstance.pid);
3165
+ if (!isRun) {
3166
+ removePidFile();
3167
+ logInfo("[i] Adspower program is not running");
3168
+ return;
3169
+ }
3170
+ const status = processInstance.status;
3171
+ if (status === "starting") {
3172
+ logSuccess("[i] Adspower program is starting...");
3173
+ } else if (status === "doing" && processInstance.apiPort) {
3174
+ logSuccess("[i] Adspower program is running at:");
3175
+ logSuccess(` - http://local.adspower.net:${processInstance.apiPort}`);
3176
+ } else if (status === "stop") {
3177
+ logInfo("[i] Adspower program is stopped");
3178
+ } else {
3179
+ logInfo("[i] Adspower program is not started");
3180
+ }
3181
+ } else {
3182
+ logInfo("[i] Adspower program is not running");
3183
+ }
3184
+ };
3185
+
3186
+ // src/startConfig.ts
3187
+ var MISSING_API_KEY_ERROR = "error: required option '-k, --api-key <apiKey>' not specified";
3188
+ function resolveStartApiKey(optionApiKey, env = process.env) {
3189
+ if (optionApiKey) {
3190
+ return {
3191
+ ok: true,
3192
+ apiKey: optionApiKey
3193
+ };
3194
+ }
3195
+ if (env.ADS_API_KEY) {
3196
+ return {
3197
+ ok: true,
3198
+ apiKey: env.ADS_API_KEY
3199
+ };
3200
+ }
3201
+ return {
3202
+ ok: false,
3203
+ error: MISSING_API_KEY_ERROR
3204
+ };
3205
+ }
3206
+
3207
+ // src/completion.ts
3208
+ var import_commander = __toESM(require("@bomb.sh/tab/commander"));
3209
+ var CLI_BIN_ALIASES = ["ads", "adspower", "adspower-browser"];
3210
+ function patchShellCompletionScript(shell, script) {
3211
+ if (shell === "zsh") {
3212
+ return script.replace(/^#compdef .+$/m, `#compdef ${CLI_BIN_ALIASES.join(" ")}`).replace(/^compdef _ads ads$/m, `compdef _ads ${CLI_BIN_ALIASES.join(" ")}`);
3213
+ }
3214
+ if (shell === "bash") {
3215
+ return script.replace(
3216
+ /^complete -F __ads_complete ads$/m,
3217
+ `complete -F __ads_complete ${CLI_BIN_ALIASES.join(" ")}`
3218
+ );
3219
+ }
3220
+ return script;
3221
+ }
3222
+ function setupShellCompletion(program2) {
3223
+ program2.name("ads");
3224
+ (0, import_commander.default)(program2);
3225
+ }
3226
+ function isShellCompletionRequest(argv = process.argv) {
3227
+ const completionIndex = argv.indexOf("complete");
3228
+ const dashDashIndex = argv.indexOf("--");
3229
+ return completionIndex !== -1 && dashDashIndex !== -1 && dashDashIndex > completionIndex;
3230
+ }
3231
+ function wrapShellScriptOutput(shell) {
3232
+ if (shell !== "zsh" && shell !== "bash") {
3233
+ return () => {
3234
+ };
3235
+ }
3236
+ const originalWrite = process.stdout.write.bind(process.stdout);
3237
+ process.stdout.write = ((chunk, encoding, callback) => {
3238
+ const text = typeof chunk === "string" ? chunk : Buffer.from(chunk).toString(typeof encoding === "string" ? encoding : "utf8");
3239
+ const patched = patchShellCompletionScript(shell, text);
3240
+ if (typeof encoding === "function") {
3241
+ return originalWrite(patched, encoding);
3242
+ }
3243
+ return originalWrite(
3244
+ patched,
3245
+ encoding,
3246
+ callback
3247
+ );
3248
+ });
3249
+ return () => {
3250
+ process.stdout.write = originalWrite;
3251
+ };
3057
3252
  }
3058
3253
 
3059
3254
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adspower-browser",
3
- "version": "2.0.6",
3
+ "version": "2.0.7",
4
4
  "main": "cli/index.js",
5
5
  "type": "commonjs",
6
6
  "bin": {