tt-help-cli-ycl 1.4.79 → 1.4.82

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tt-help-cli-ycl",
3
- "version": "1.4.79",
3
+ "version": "1.4.82",
4
4
  "description": "TikTok user & video data scraper - extract ttSeller, verified, locationCreated from HTML source",
5
5
  "type": "module",
6
6
  "bin": {
package/src/clash/api.js CHANGED
@@ -101,6 +101,23 @@ export async function getNodes() {
101
101
  export async function getConfigs() {
102
102
  return request("/configs");
103
103
  }
104
+
105
+ /**
106
+ * 从 Clash API 自动发现代理端口(mixed-port)
107
+ * 无需依赖任何配置文件,直接问 Clash 自己
108
+ * @returns {Promise<string>} 代理 URL,如 "http://127.0.0.1:7897"
109
+ */
110
+ export async function resolveProxyUrl() {
111
+ try {
112
+ const configs = await getConfigs();
113
+ const port = configs?.["mixed-port"] || 7897;
114
+ return `http://127.0.0.1:${port}`;
115
+ } catch {
116
+ // Clash API 不可达,回退到默认值
117
+ return "http://127.0.0.1:7897";
118
+ }
119
+ }
120
+
104
121
  export async function patchConfigs(patch) {
105
122
  return request("/configs", { method: "PATCH", body: JSON.stringify(patch) });
106
123
  }
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Clash Verge (mihomo) RESTful API 客户端
3
+ *
4
+ * API 参考: https://wiki.metacubex.one/en/api
5
+ * 认证方式: Authorization: Bearer ${secret}
6
+ * 依赖 Clash Verge GUI 运行时绑定的 TCP 127.0.0.1:9097
7
+ */
8
+
9
+ const BASE_URL = "http://127.0.0.1:9097";
10
+ const SECRET = "abcdefg";
11
+
12
+ function headers() {
13
+ return {
14
+ Authorization: `Bearer ${SECRET}`,
15
+ "Content-Type": "application/json",
16
+ };
17
+ }
18
+
19
+ async function request(path, options = {}) {
20
+ const url = `${BASE_URL}${path}`;
21
+ const res = await fetch(url, {
22
+ ...options,
23
+ headers: { ...headers(), ...options.headers },
24
+ });
25
+ if (!res.ok) {
26
+ const body = await res.text().catch(() => "");
27
+ throw new Error(`HTTP ${res.status} ${res.statusText}: ${body}`);
28
+ }
29
+ if (res.status === 204) return null;
30
+ const text = await res.text();
31
+ return text ? JSON.parse(text) : null;
32
+ }
33
+
34
+ // ===== 代理相关 =====
35
+
36
+ /** 获取所有代理(含代理组和节点) */
37
+ export async function getProxies() {
38
+ return request("/proxies");
39
+ }
40
+
41
+ /** 获取单个代理/组详情 */
42
+ export async function getProxy(name) {
43
+ return request(`/proxies/${encodeURIComponent(name)}`);
44
+ }
45
+
46
+ /** 切换代理组的选中节点 */
47
+ export async function switchProxy(groupName, nodeName) {
48
+ return request(`/proxies/${encodeURIComponent(groupName)}`, {
49
+ method: "PUT",
50
+ body: JSON.stringify({ name: nodeName }),
51
+ });
52
+ }
53
+
54
+ /**
55
+ * 获取所有代理组(Selector/URLTest/Fallback/LoadBalance 类型)
56
+ * 返回: [{ name, type, now, all }]
57
+ */
58
+ export async function getGroups() {
59
+ const data = await getProxies();
60
+ const proxies = data.proxies || {};
61
+ const groups = [];
62
+ const groupTypes = new Set([
63
+ "Selector",
64
+ "URLTest",
65
+ "Fallback",
66
+ "LoadBalance",
67
+ ]);
68
+
69
+ for (const [name, info] of Object.entries(proxies)) {
70
+ if (groupTypes.has(info.type)) {
71
+ groups.push({
72
+ name,
73
+ type: info.type,
74
+ now: info.now || "",
75
+ all: info.all || [],
76
+ });
77
+ }
78
+ }
79
+ return groups;
80
+ }
81
+
82
+ /**
83
+ * 获取所有独立节点(非代理组)
84
+ * 返回: [{ name, type, alive, delay }]
85
+ */
86
+ export async function getNodes() {
87
+ const data = await getProxies();
88
+ const proxies = data.proxies || {};
89
+ const nodes = [];
90
+ const groupTypes = new Set([
91
+ "Selector",
92
+ "URLTest",
93
+ "Fallback",
94
+ "LoadBalance",
95
+ ]);
96
+
97
+ for (const [name, info] of Object.entries(proxies)) {
98
+ if (!groupTypes.has(info.type)) {
99
+ nodes.push({
100
+ name,
101
+ type: info.type,
102
+ alive: info.alive ?? false,
103
+ delay:
104
+ info.history?.length > 0
105
+ ? info.history[info.history.length - 1].delay
106
+ : null,
107
+ udp: info.udp ?? false,
108
+ });
109
+ }
110
+ }
111
+ return nodes;
112
+ }
113
+
114
+ // ===== 配置相关 =====
115
+
116
+ /** 获取当前运行配置 */
117
+ export async function getConfigs() {
118
+ return request("/configs");
119
+ }
120
+
121
+ /** 更新运行配置(部分更新) */
122
+ export async function patchConfigs(patch) {
123
+ return request("/configs", {
124
+ method: "PATCH",
125
+ body: JSON.stringify(patch),
126
+ });
127
+ }
128
+
129
+ /** 强制重载配置 */
130
+ export async function reloadConfigs() {
131
+ return request("/configs?force=true", { method: "PUT" });
132
+ }
133
+
134
+ // ===== 系统 =====
135
+
136
+ /** 获取内核版本 */
137
+ export async function getVersion() {
138
+ return request("/version");
139
+ }
140
+
141
+ /** 获取内存使用 */
142
+ export async function getMemory() {
143
+ return request("/memory");
144
+ }
145
+
146
+ // ===== 连接 =====
147
+
148
+ /** 获取当前活跃连接 */
149
+ export async function getConnections() {
150
+ return request("/connections");
151
+ }
152
+
153
+ /** 关闭指定连接 */
154
+ export async function closeConnection(id) {
155
+ return request(`/connections/${id}`, { method: "DELETE" });
156
+ }
157
+
158
+ /** 关闭所有连接 */
159
+ export async function closeAllConnections() {
160
+ return request("/connections", { method: "DELETE" });
161
+ }
162
+
163
+ // ===== 规则 =====
164
+
165
+ /** 获取规则列表 */
166
+ export async function getRules() {
167
+ return request("/rules");
168
+ }
169
+
170
+ // ===== 代理提供者 =====
171
+
172
+ /** 获取代理提供者列表 */
173
+ export async function getProxyProviders() {
174
+ return request("/providers/proxies");
175
+ }
176
+
177
+ /** 更新代理提供者 */
178
+ export async function updateProxyProvider(name) {
179
+ return request(`/providers/proxies/${encodeURIComponent(name)}`, {
180
+ method: "PUT",
181
+ });
182
+ }
183
+
184
+ /** 代理提供者健康检查 */
185
+ export async function healthCheckProvider(name) {
186
+ return request(`/providers/proxies/${encodeURIComponent(name)}/healthcheck`);
187
+ }
188
+
189
+ // ===== 便捷函数 =====
190
+
191
+ /**
192
+ * 获取指定组当前选中节点
193
+ */
194
+ export async function getCurrentNode(groupName) {
195
+ const proxy = await getProxy(groupName);
196
+ return proxy.now || null;
197
+ }
198
+
199
+ /**
200
+ * 列出指定组的所有可选节点
201
+ */
202
+ export async function listGroupNodes(groupName) {
203
+ const proxy = await getProxy(groupName);
204
+ return proxy.all || [];
205
+ }
206
+
207
+ /**
208
+ * 获取所有存活节点(按延迟排序)
209
+ */
210
+ export async function getAliveNodes() {
211
+ const nodes = await getNodes();
212
+ return nodes
213
+ .filter((n) => n.alive && n.delay !== null && n.delay > 0)
214
+ .sort((a, b) => (a.delay ?? Infinity) - (b.delay ?? Infinity));
215
+ }
216
+
217
+ /**
218
+ * 切换到延迟最低的存活节点
219
+ */
220
+ export async function switchToFastest(groupName) {
221
+ const alive = await getAliveNodes();
222
+ if (alive.length === 0) {
223
+ throw new Error("没有存活的节点");
224
+ }
225
+ // 需要确认目标节点在该组的 all 列表中
226
+ const groupNodes = await listGroupNodes(groupName);
227
+ for (const node of alive) {
228
+ if (groupNodes.includes(node.name)) {
229
+ await switchProxy(groupName, node.name);
230
+ return node;
231
+ }
232
+ }
233
+ throw new Error("存活节点都不在目标组中");
234
+ }
@@ -0,0 +1,431 @@
1
+ {
2
+ "testTime": "2026-08-10T08:47:10.485Z",
3
+ "target": "https://www.tiktok.com",
4
+ "summary": {
5
+ "total": 30,
6
+ "real": 17,
7
+ "redirect": 2,
8
+ "waf": 7,
9
+ "dead": 4,
10
+ "blocked": 0
11
+ },
12
+ "realNodes": [
13
+ {
14
+ "node": "🇯🇵日本Trojan1",
15
+ "type": "Trojan",
16
+ "timeTotal": 1.174005,
17
+ "timeConnect": 0.000338,
18
+ "sizeDownload": 12579
19
+ },
20
+ {
21
+ "node": "🇷🇺俄罗斯HY专线去广告",
22
+ "type": "Hysteria2",
23
+ "timeTotal": 1.269673,
24
+ "timeConnect": 0.00025,
25
+ "sizeDownload": 12579
26
+ },
27
+ {
28
+ "node": "🇬🇧英国HY1-1000M专线",
29
+ "type": "Hysteria2",
30
+ "timeTotal": 1.357936,
31
+ "timeConnect": 0.000343,
32
+ "sizeDownload": 364873
33
+ },
34
+ {
35
+ "node": "🇺🇸美国HY2轻量-小火箭也能用HY",
36
+ "type": "Hysteria2",
37
+ "timeTotal": 1.512879,
38
+ "timeConnect": 0.000324,
39
+ "sizeDownload": 363070
40
+ },
41
+ {
42
+ "node": "🇺🇸美国HY5神速-推荐",
43
+ "type": "Hysteria2",
44
+ "timeTotal": 1.632324,
45
+ "timeConnect": 0.000263,
46
+ "sizeDownload": 363348
47
+ },
48
+ {
49
+ "node": "🇺🇸美国HY3神速-小火箭无延迟也能用",
50
+ "type": "Hysteria2",
51
+ "timeTotal": 1.659374,
52
+ "timeConnect": 0.000399,
53
+ "sizeDownload": 361805
54
+ },
55
+ {
56
+ "node": "🇺🇸美国HY1轻量",
57
+ "type": "Hysteria2",
58
+ "timeTotal": 1.793751,
59
+ "timeConnect": 0.000252,
60
+ "sizeDownload": 362788
61
+ },
62
+ {
63
+ "node": "🇺🇸美国光速1-解锁GPT",
64
+ "type": "Trojan",
65
+ "timeTotal": 1.910699,
66
+ "timeConnect": 0.000271,
67
+ "sizeDownload": 362778
68
+ },
69
+ {
70
+ "node": "🇺🇸美国HY高速V6",
71
+ "type": "Hysteria2",
72
+ "timeTotal": 2.079931,
73
+ "timeConnect": 0.000351,
74
+ "sizeDownload": 362679
75
+ },
76
+ {
77
+ "node": "🇬🇧英国trojan1",
78
+ "type": "Trojan",
79
+ "timeTotal": 2.646707,
80
+ "timeConnect": 0.00038,
81
+ "sizeDownload": 364594
82
+ },
83
+ {
84
+ "node": "🇺🇸美国2-baipiaoyes.top",
85
+ "type": "Trojan",
86
+ "timeTotal": 3.019101,
87
+ "timeConnect": 0.000339,
88
+ "sizeDownload": 363541
89
+ },
90
+ {
91
+ "node": "🇷🇺去油管广告",
92
+ "type": "Trojan",
93
+ "timeTotal": 4.092772,
94
+ "timeConnect": 0.000307,
95
+ "sizeDownload": 390066
96
+ },
97
+ {
98
+ "node": "🇯🇵日本Trojan3",
99
+ "type": "Trojan",
100
+ "timeTotal": 4.212222,
101
+ "timeConnect": 0.000397,
102
+ "sizeDownload": 12579
103
+ },
104
+ {
105
+ "node": "🇺🇸美国HY4神速-1000M",
106
+ "type": "Hysteria2",
107
+ "timeTotal": 4.569531,
108
+ "timeConnect": 0.000262,
109
+ "sizeDownload": 362573
110
+ },
111
+ {
112
+ "node": "🇺🇸美国-快",
113
+ "type": "Vless",
114
+ "timeTotal": 4.572119,
115
+ "timeConnect": 0.000403,
116
+ "sizeDownload": 362706
117
+ },
118
+ {
119
+ "node": "🇺🇸美国V6666",
120
+ "type": "Vless",
121
+ "timeTotal": 5.088888,
122
+ "timeConnect": 0.000237,
123
+ "sizeDownload": 362522
124
+ },
125
+ {
126
+ "node": "🇯🇵日本Trojan2",
127
+ "type": "Trojan",
128
+ "timeTotal": 6.612371,
129
+ "timeConnect": 0.000275,
130
+ "sizeDownload": 12579
131
+ }
132
+ ],
133
+ "allResults": [
134
+ {
135
+ "node": "Youtube去广告1",
136
+ "type": "Trojan",
137
+ "category": "dead",
138
+ "httpCode": 0,
139
+ "timeTotal": 12,
140
+ "sizeDownload": 0,
141
+ "error": "exit 28"
142
+ },
143
+ {
144
+ "node": "🇬🇧英国HY1-1000M专线",
145
+ "type": "Hysteria2",
146
+ "category": "real",
147
+ "httpCode": 200,
148
+ "timeTotal": 1.357936,
149
+ "sizeDownload": 364873,
150
+ "title": "TikTok - Make Your Day",
151
+ "error": null
152
+ },
153
+ {
154
+ "node": "🇬🇧英国trojan1",
155
+ "type": "Trojan",
156
+ "category": "real",
157
+ "httpCode": 200,
158
+ "timeTotal": 2.646707,
159
+ "sizeDownload": 364594,
160
+ "title": "TikTok - Make Your Day",
161
+ "error": null
162
+ },
163
+ {
164
+ "node": "🇬🇧英国trojan2",
165
+ "type": "Trojan",
166
+ "category": "dead",
167
+ "httpCode": 0,
168
+ "timeTotal": 12,
169
+ "sizeDownload": 0,
170
+ "error": "exit 35"
171
+ },
172
+ {
173
+ "node": "🇭🇰香港Gemini",
174
+ "type": "Vless",
175
+ "category": "redirect",
176
+ "httpCode": 200,
177
+ "timeTotal": 1.655845,
178
+ "sizeDownload": 181106,
179
+ "title": "About | TikTok",
180
+ "error": null
181
+ },
182
+ {
183
+ "node": "🇭🇰香港HY1-1000M专线",
184
+ "type": "Hysteria2",
185
+ "category": "waf",
186
+ "httpCode": 200,
187
+ "timeTotal": 0.370995,
188
+ "sizeDownload": 1462,
189
+ "title": "",
190
+ "error": null
191
+ },
192
+ {
193
+ "node": "🇭🇰香港trojan2",
194
+ "type": "Trojan",
195
+ "category": "redirect",
196
+ "httpCode": 200,
197
+ "timeTotal": 4.38978,
198
+ "sizeDownload": 181106,
199
+ "title": "About | TikTok",
200
+ "error": null
201
+ },
202
+ {
203
+ "node": "🇯🇵日本Trojan1",
204
+ "type": "Trojan",
205
+ "category": "real",
206
+ "httpCode": 200,
207
+ "timeTotal": 1.174005,
208
+ "sizeDownload": 12579,
209
+ "title": "",
210
+ "error": null
211
+ },
212
+ {
213
+ "node": "🇯🇵日本Trojan2",
214
+ "type": "Trojan",
215
+ "category": "real",
216
+ "httpCode": 200,
217
+ "timeTotal": 6.612371,
218
+ "sizeDownload": 12579,
219
+ "title": "",
220
+ "error": null
221
+ },
222
+ {
223
+ "node": "🇯🇵日本Trojan3",
224
+ "type": "Trojan",
225
+ "category": "real",
226
+ "httpCode": 200,
227
+ "timeTotal": 4.212222,
228
+ "sizeDownload": 12579,
229
+ "title": "",
230
+ "error": null
231
+ },
232
+ {
233
+ "node": "🇲🇾马来西亚Trojan1",
234
+ "type": "Trojan",
235
+ "category": "waf",
236
+ "httpCode": 200,
237
+ "timeTotal": 0.702351,
238
+ "sizeDownload": 1462,
239
+ "title": "",
240
+ "error": null
241
+ },
242
+ {
243
+ "node": "🇲🇾马来西亚Trojan2",
244
+ "type": "Trojan",
245
+ "category": "waf",
246
+ "httpCode": 200,
247
+ "timeTotal": 1.593941,
248
+ "sizeDownload": 1462,
249
+ "title": "",
250
+ "error": null
251
+ },
252
+ {
253
+ "node": "🇷🇺俄罗斯HY专线去广告",
254
+ "type": "Hysteria2",
255
+ "category": "real",
256
+ "httpCode": 200,
257
+ "timeTotal": 1.269673,
258
+ "sizeDownload": 12579,
259
+ "title": "",
260
+ "error": null
261
+ },
262
+ {
263
+ "node": "🇷🇺俄罗斯V6-油管去广告",
264
+ "type": "Vless",
265
+ "category": "waf",
266
+ "httpCode": 200,
267
+ "timeTotal": 2.011837,
268
+ "sizeDownload": 1462,
269
+ "title": "",
270
+ "error": null
271
+ },
272
+ {
273
+ "node": "🇷🇺去油管广告",
274
+ "type": "Trojan",
275
+ "category": "real",
276
+ "httpCode": 200,
277
+ "timeTotal": 4.092772,
278
+ "sizeDownload": 390066,
279
+ "title": "TikTok - Make Your Day",
280
+ "error": null
281
+ },
282
+ {
283
+ "node": "🇸🇬新加坡Trojan1",
284
+ "type": "Trojan",
285
+ "category": "waf",
286
+ "httpCode": 200,
287
+ "timeTotal": 0.56045,
288
+ "sizeDownload": 1462,
289
+ "title": "",
290
+ "error": null
291
+ },
292
+ {
293
+ "node": "🇹🇼台湾trojan1",
294
+ "type": "Trojan",
295
+ "category": "waf",
296
+ "httpCode": 200,
297
+ "timeTotal": 3.067687,
298
+ "sizeDownload": 1462,
299
+ "title": "",
300
+ "error": null
301
+ },
302
+ {
303
+ "node": "🇹🇼台湾trojan2",
304
+ "type": "Trojan",
305
+ "category": "dead",
306
+ "httpCode": 0,
307
+ "timeTotal": 12,
308
+ "sizeDownload": 0,
309
+ "error": "exit 35"
310
+ },
311
+ {
312
+ "node": "🇹🇼台湾trojan直连",
313
+ "type": "Trojan",
314
+ "category": "waf",
315
+ "httpCode": 200,
316
+ "timeTotal": 6.785391,
317
+ "sizeDownload": 1462,
318
+ "title": "",
319
+ "error": null
320
+ },
321
+ {
322
+ "node": "🇺🇸美国-快",
323
+ "type": "Vless",
324
+ "category": "real",
325
+ "httpCode": 200,
326
+ "timeTotal": 4.572119,
327
+ "sizeDownload": 362706,
328
+ "title": "TikTok - Make Your Day",
329
+ "error": null
330
+ },
331
+ {
332
+ "node": "🇺🇸美国1-baipiaoyes.top",
333
+ "type": "Trojan",
334
+ "category": "dead",
335
+ "httpCode": 0,
336
+ "timeTotal": 12,
337
+ "sizeDownload": 0,
338
+ "error": "exit 28"
339
+ },
340
+ {
341
+ "node": "🇺🇸美国2-baipiaoyes.top",
342
+ "type": "Trojan",
343
+ "category": "real",
344
+ "httpCode": 200,
345
+ "timeTotal": 3.019101,
346
+ "sizeDownload": 363541,
347
+ "title": "TikTok - Make Your Day",
348
+ "error": null
349
+ },
350
+ {
351
+ "node": "🇺🇸美国HY1轻量",
352
+ "type": "Hysteria2",
353
+ "category": "real",
354
+ "httpCode": 200,
355
+ "timeTotal": 1.793751,
356
+ "sizeDownload": 362788,
357
+ "title": "TikTok - Make Your Day",
358
+ "error": null
359
+ },
360
+ {
361
+ "node": "🇺🇸美国HY2轻量-小火箭也能用HY",
362
+ "type": "Hysteria2",
363
+ "category": "real",
364
+ "httpCode": 200,
365
+ "timeTotal": 1.512879,
366
+ "sizeDownload": 363070,
367
+ "title": "TikTok - Make Your Day",
368
+ "error": null
369
+ },
370
+ {
371
+ "node": "🇺🇸美国HY3神速-小火箭无延迟也能用",
372
+ "type": "Hysteria2",
373
+ "category": "real",
374
+ "httpCode": 200,
375
+ "timeTotal": 1.659374,
376
+ "sizeDownload": 361805,
377
+ "title": "TikTok - Make Your Day",
378
+ "error": null
379
+ },
380
+ {
381
+ "node": "🇺🇸美国HY4神速-1000M",
382
+ "type": "Hysteria2",
383
+ "category": "real",
384
+ "httpCode": 200,
385
+ "timeTotal": 4.569531,
386
+ "sizeDownload": 362573,
387
+ "title": "TikTok - Make Your Day",
388
+ "error": null
389
+ },
390
+ {
391
+ "node": "🇺🇸美国HY5神速-推荐",
392
+ "type": "Hysteria2",
393
+ "category": "real",
394
+ "httpCode": 200,
395
+ "timeTotal": 1.632324,
396
+ "sizeDownload": 363348,
397
+ "title": "TikTok - Make Your Day",
398
+ "error": null
399
+ },
400
+ {
401
+ "node": "🇺🇸美国HY高速V6",
402
+ "type": "Hysteria2",
403
+ "category": "real",
404
+ "httpCode": 200,
405
+ "timeTotal": 2.079931,
406
+ "sizeDownload": 362679,
407
+ "title": "TikTok - Make Your Day",
408
+ "error": null
409
+ },
410
+ {
411
+ "node": "🇺🇸美国V6666",
412
+ "type": "Vless",
413
+ "category": "real",
414
+ "httpCode": 200,
415
+ "timeTotal": 5.088888,
416
+ "sizeDownload": 362522,
417
+ "title": "TikTok - Make Your Day",
418
+ "error": null
419
+ },
420
+ {
421
+ "node": "🇺🇸美国光速1-解锁GPT",
422
+ "type": "Trojan",
423
+ "category": "real",
424
+ "httpCode": 200,
425
+ "timeTotal": 1.910699,
426
+ "sizeDownload": 362778,
427
+ "title": "TikTok - Make Your Day",
428
+ "error": null
429
+ }
430
+ ]
431
+ }