adspower-browser 2.0.3 → 2.0.5
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 +32 -5
- package/cli/core/winHideChildProcess.js +47 -0
- package/cli/index.js +25 -9
- package/package.json +1 -1
package/README.MD
CHANGED
|
@@ -65,7 +65,7 @@ ads start
|
|
|
65
65
|
|
|
66
66
|
The CLI supports prefix tab completion for subcommands and common flags (`-k`, `-p`, etc.) via [`@bomb.sh/tab`](https://bomb.sh/docs/tab/). Enable it once in your shell:
|
|
67
67
|
|
|
68
|
-
**zsh**
|
|
68
|
+
**macOS — zsh**
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
71
|
ads complete zsh > ~/.ads-completion.zsh
|
|
@@ -73,7 +73,7 @@ echo 'source ~/.ads-completion.zsh' >> ~/.zshrc
|
|
|
73
73
|
source ~/.ads-completion.zsh
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
**bash**
|
|
76
|
+
**Linux — bash**
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
79
|
ads complete bash > ~/.ads-completion.bash
|
|
@@ -81,7 +81,34 @@ echo 'source ~/.ads-completion.bash' >> ~/.bashrc
|
|
|
81
81
|
source ~/.ads-completion.bash
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
On Linux login shells, ensure `~/.bashrc` is sourced (e.g. from `~/.bash_profile`).
|
|
85
|
+
|
|
86
|
+
**Linux — zsh**
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ads complete zsh > ~/.ads-completion.zsh
|
|
90
|
+
echo 'source ~/.ads-completion.zsh' >> ~/.zshrc
|
|
91
|
+
source ~/.ads-completion.zsh
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Windows — PowerShell**
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
ads complete powershell > $HOME\.ads-completion.ps1
|
|
98
|
+
if (-not (Test-Path $PROFILE)) { New-Item -Path $PROFILE -ItemType File -Force }
|
|
99
|
+
Add-Content $PROFILE '. $HOME\.ads-completion.ps1'
|
|
100
|
+
. $HOME\.ads-completion.ps1
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Windows — Git Bash**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
ads complete bash > ~/.ads-completion.bash
|
|
107
|
+
echo 'source ~/.ads-completion.bash' >> ~/.bashrc
|
|
108
|
+
source ~/.ads-completion.bash
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
After setup on zsh/bash, `ads`, `adspower`, and `adspower-browser` share the same completions. On PowerShell and Git Bash, use `ads` for tab completion:
|
|
85
112
|
|
|
86
113
|
```bash
|
|
87
114
|
ads <Tab><Tab> # list subcommands
|
|
@@ -115,7 +142,7 @@ ads close-browser <profile_id> # Or JSON: profile_id? | profil
|
|
|
115
142
|
ads create-browser '{"group_id":"0","user_proxy_config":{"proxy_soft":"no_proxy"},...}' # group_id + account field required; proxy optional (defaults to no_proxy; proxyid takes priority over user_proxy_config when both given)
|
|
116
143
|
ads update-browser '{"profile_id":"...",...}' # profile_id required
|
|
117
144
|
ads delete-browser '{"profile_id":["..."]}' # profile_id required
|
|
118
|
-
ads get-browser-list '{}' # Or group_id?, limit?, page?, profile_id[]?, profile_no[]?, sort_type?, sort_order?, tag_ids?, tags_filter?, name?, name_filter?
|
|
145
|
+
ads get-browser-list '{}' # CLI defaults to page=1,limit=200. Or group_id?, limit?, page?, profile_id[]?, profile_no[]?, sort_type?, sort_order?, tag_ids?, tags_filter?, name?, name_filter?
|
|
119
146
|
ads get-opened-browser # No params
|
|
120
147
|
```
|
|
121
148
|
|
|
@@ -187,4 +214,4 @@ copy the [`docker-compose.yml`](./docker-compose.yml)
|
|
|
187
214
|
docker-compose -f ./docker-compose.yml up -d
|
|
188
215
|
|
|
189
216
|
docker-compose exec adspower-cli /bin/bash
|
|
190
|
-
```
|
|
217
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// src/core/winHideChildProcess.js
|
|
4
|
+
if (process.platform !== "win32") {
|
|
5
|
+
return;
|
|
6
|
+
}
|
|
7
|
+
var cp = require("child_process");
|
|
8
|
+
function withWindowsHide(options) {
|
|
9
|
+
if (typeof options === "object" && options !== null && !Array.isArray(options)) {
|
|
10
|
+
if (options.windowsHide === false) {
|
|
11
|
+
return options;
|
|
12
|
+
}
|
|
13
|
+
return { ...options, windowsHide: true };
|
|
14
|
+
}
|
|
15
|
+
return { windowsHide: true };
|
|
16
|
+
}
|
|
17
|
+
function normalizeExecArgs(options, callback) {
|
|
18
|
+
if (typeof options === "function") {
|
|
19
|
+
return { options: { windowsHide: true }, callback: options };
|
|
20
|
+
}
|
|
21
|
+
return { options: withWindowsHide(options || {}), callback };
|
|
22
|
+
}
|
|
23
|
+
function normalizeSpawnArgs(args, options) {
|
|
24
|
+
if (Array.isArray(args)) {
|
|
25
|
+
return { args, options: withWindowsHide(options || {}) };
|
|
26
|
+
}
|
|
27
|
+
return { args: [], options: withWindowsHide(args || {}) };
|
|
28
|
+
}
|
|
29
|
+
var origExec = cp.exec.bind(cp);
|
|
30
|
+
cp.exec = function exec(cmd, options, callback) {
|
|
31
|
+
const { options: opts, callback: cb } = normalizeExecArgs(options, callback);
|
|
32
|
+
return origExec(cmd, opts, cb);
|
|
33
|
+
};
|
|
34
|
+
var origExecSync = cp.execSync.bind(cp);
|
|
35
|
+
cp.execSync = function execSync(cmd, options) {
|
|
36
|
+
return origExecSync(cmd, withWindowsHide(options || {}));
|
|
37
|
+
};
|
|
38
|
+
var origSpawn = cp.spawn.bind(cp);
|
|
39
|
+
cp.spawn = function spawn(command, args, options) {
|
|
40
|
+
const normalized = normalizeSpawnArgs(args, options);
|
|
41
|
+
return origSpawn(command, normalized.args, normalized.options);
|
|
42
|
+
};
|
|
43
|
+
var origSpawnSync = cp.spawnSync.bind(cp);
|
|
44
|
+
cp.spawnSync = function spawnSync(command, args, options) {
|
|
45
|
+
const normalized = normalizeSpawnArgs(args, options);
|
|
46
|
+
return origSpawnSync(command, normalized.args, normalized.options);
|
|
47
|
+
};
|
package/cli/index.js
CHANGED
|
@@ -93,6 +93,7 @@ var Store = class {
|
|
|
93
93
|
var store = new Store();
|
|
94
94
|
|
|
95
95
|
// src/core/start.ts
|
|
96
|
+
var fs2 = __toESM(require("fs"));
|
|
96
97
|
var path2 = __toESM(require("path"));
|
|
97
98
|
var import_node_child_process2 = require("child_process");
|
|
98
99
|
|
|
@@ -134,7 +135,7 @@ var browsersKill = async () => {
|
|
|
134
135
|
};
|
|
135
136
|
var taskKillBrowser = () => new Promise((resolve) => {
|
|
136
137
|
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "SunBrowser"' : "taskkill -PID SunBrowser.exe";
|
|
137
|
-
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
138
|
+
(0, import_node_child_process.exec)(cmd, { windowsHide: true }, (err) => {
|
|
138
139
|
if (err) {
|
|
139
140
|
}
|
|
140
141
|
resolve();
|
|
@@ -142,7 +143,7 @@ var taskKillBrowser = () => new Promise((resolve) => {
|
|
|
142
143
|
});
|
|
143
144
|
var taskKillFlowser = () => new Promise((resolve) => {
|
|
144
145
|
const cmd = ["linux", "darwin"].includes(process.platform) ? 'pkill -u `whoami` -f "FlowerBrowser"' : "taskkill -PID FlowerBrowser.exe";
|
|
145
|
-
(0, import_node_child_process.exec)(cmd, (err) => {
|
|
146
|
+
(0, import_node_child_process.exec)(cmd, { windowsHide: true }, (err) => {
|
|
146
147
|
if (err) {
|
|
147
148
|
}
|
|
148
149
|
resolve();
|
|
@@ -184,6 +185,7 @@ var isRunning = (pid) => {
|
|
|
184
185
|
if (pid) {
|
|
185
186
|
(0, import_node_child_process.exec)(
|
|
186
187
|
util.format(process.platform === "win32" ? 'tasklist /fi "PID eq %s" | findstr /i "node.exe"' : 'ps -f -p %s | grep "node"', pid),
|
|
188
|
+
{ windowsHide: true },
|
|
187
189
|
function(err, stdout, stderr) {
|
|
188
190
|
resolve(!err && !!stdout.toString().trim());
|
|
189
191
|
}
|
|
@@ -288,6 +290,16 @@ var initSqlite3 = () => {
|
|
|
288
290
|
};
|
|
289
291
|
|
|
290
292
|
// src/core/start.ts
|
|
293
|
+
var getRuntimeExecArgv = () => {
|
|
294
|
+
if (process.platform !== "win32") {
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
const preload = path2.join(__dirname, "core/winHideChildProcess.js");
|
|
298
|
+
if (!fs2.existsSync(preload)) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
return ["--require", preload];
|
|
302
|
+
};
|
|
291
303
|
var getEnv = () => {
|
|
292
304
|
const env = {
|
|
293
305
|
...process.env,
|
|
@@ -328,7 +340,8 @@ var startChild = (type) => {
|
|
|
328
340
|
detached: true,
|
|
329
341
|
windowsHide: true,
|
|
330
342
|
// 隐藏子进程的控制台窗口
|
|
331
|
-
stdio: ["ignore", "ignore", "ignore", "ipc"]
|
|
343
|
+
stdio: ["ignore", "ignore", "ignore", "ipc"],
|
|
344
|
+
execArgv: getRuntimeExecArgv()
|
|
332
345
|
};
|
|
333
346
|
child = (0, import_node_child_process2.fork)(mainJs, [], forkOptions);
|
|
334
347
|
ensureBrowserPath();
|
|
@@ -657,8 +670,8 @@ var LOCAL_API_CONTRACTS = {
|
|
|
657
670
|
path: "/api/v2/browser-profile/list",
|
|
658
671
|
params: {
|
|
659
672
|
group_id: { apiName: "group_id", location: "body" },
|
|
660
|
-
limit: { apiName: "limit", location: "body" },
|
|
661
|
-
page: { apiName: "page", location: "body" },
|
|
673
|
+
limit: { apiName: "limit", location: "body", default: 200 },
|
|
674
|
+
page: { apiName: "page", location: "body", default: 1 },
|
|
662
675
|
profile_id: { apiName: "profile_id", location: "body" },
|
|
663
676
|
profile_no: { apiName: "profile_no", location: "body" },
|
|
664
677
|
sort_type: { apiName: "sort_type", location: "body" },
|
|
@@ -1274,6 +1287,9 @@ function toContractValue(value) {
|
|
|
1274
1287
|
}
|
|
1275
1288
|
return value;
|
|
1276
1289
|
}
|
|
1290
|
+
function withContractDefault(value, defaultValue) {
|
|
1291
|
+
return value === void 0 ? defaultValue : value;
|
|
1292
|
+
}
|
|
1277
1293
|
function buildRequestBodyFor(command, params) {
|
|
1278
1294
|
const requestBody = {};
|
|
1279
1295
|
const contract = LOCAL_API_CONTRACTS[command];
|
|
@@ -1281,7 +1297,7 @@ function buildRequestBodyFor(command, params) {
|
|
|
1281
1297
|
if (config2.location !== "body") {
|
|
1282
1298
|
return;
|
|
1283
1299
|
}
|
|
1284
|
-
const value = params[inputName];
|
|
1300
|
+
const value = withContractDefault(params[inputName], config2.default);
|
|
1285
1301
|
if (value !== void 0) {
|
|
1286
1302
|
requestBody[config2.apiName] = toContractValue(value);
|
|
1287
1303
|
}
|
|
@@ -1295,7 +1311,7 @@ function buildQueryParamsFor(command, params) {
|
|
|
1295
1311
|
if (config2.location !== "query") {
|
|
1296
1312
|
return;
|
|
1297
1313
|
}
|
|
1298
|
-
const value = params[inputName];
|
|
1314
|
+
const value = withContractDefault(params[inputName], config2.default);
|
|
1299
1315
|
if (value === void 0) {
|
|
1300
1316
|
return;
|
|
1301
1317
|
}
|
|
@@ -2313,8 +2329,8 @@ var schemas = {
|
|
|
2313
2329
|
}).strict(),
|
|
2314
2330
|
getBrowserListSchema: import_zod.z.object({
|
|
2315
2331
|
group_id: import_zod.z.string().regex(/^\d+$/, "Group ID must be a numeric string").optional().describe("Query by group ID; searches all groups if empty"),
|
|
2316
|
-
limit: import_zod.z.number().min(1).max(200).optional().describe("Profiles per page.
|
|
2317
|
-
page: import_zod.z.number().min(1).optional().describe("Page number for results
|
|
2332
|
+
limit: import_zod.z.number().min(1).max(200).optional().describe("Profiles per page, range 1 ~ 200. If omitted the CLI sends limit=200; the Local API itself defaults to only 1, so always rely on this CLI default or pass an explicit value"),
|
|
2333
|
+
page: import_zod.z.number().min(1).optional().describe("Page number for results. If omitted the CLI sends page=1"),
|
|
2318
2334
|
profile_id: nonEmptyStringArraySchema.optional().describe('Query by profile ID. Example: ["h1yynkm","h1yynks"]'),
|
|
2319
2335
|
profile_no: nonEmptyStringArraySchema.optional().describe('Query by profile number. Example: ["123","124"]'),
|
|
2320
2336
|
sort_type: import_zod.z.enum(["profile_no", "last_open_time", "created_time"]).optional().describe("Sort results by: profile_no, last_open_time, or created_time"),
|