@skrillex1224/playwright-toolkit 2.1.138 → 2.1.140
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 +1 -1
- package/dist/index.cjs +148 -74
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +150 -76
- package/dist/index.js.map +3 -3
- package/index.d.ts +26 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ await Actor.exit();
|
|
|
85
85
|
| 模块 | 方法 | 说明 |
|
|
86
86
|
| ----------- | ------------------------------------------- | -------------------------------------- |
|
|
87
87
|
| `Launch` | `getAdvancedLaunchOptions()` | 增强版启动参数 |
|
|
88
|
-
| `Launch` | `getLaunchOptions()`
|
|
88
|
+
| `Launch` | `getLaunchOptions({ proxyConfiguration, log? })` | 基础启动参数(统一代理解析,可选 bypass 日志) |
|
|
89
89
|
| `Launch` | `getFingerprintGeneratorOptions()` | 指纹生成器选项 |
|
|
90
90
|
| `AntiCheat` | `applyPage(page, options?)` | 应用时区/语言/权限/视口 |
|
|
91
91
|
| `AntiCheat` | `applyContext(context, options?)` | 仅应用 Context 设置 |
|
package/dist/index.cjs
CHANGED
|
@@ -296,18 +296,18 @@ var fallbackLog = {
|
|
|
296
296
|
error: (...args) => console.error(...args),
|
|
297
297
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
298
298
|
};
|
|
299
|
-
var resolveLogMethod = (
|
|
300
|
-
if (
|
|
301
|
-
return
|
|
299
|
+
var resolveLogMethod = (logger13, name) => {
|
|
300
|
+
if (logger13 && typeof logger13[name] === "function") {
|
|
301
|
+
return logger13[name].bind(logger13);
|
|
302
302
|
}
|
|
303
|
-
if (name === "warning" &&
|
|
304
|
-
return
|
|
303
|
+
if (name === "warning" && logger13 && typeof logger13.warn === "function") {
|
|
304
|
+
return logger13.warn.bind(logger13);
|
|
305
305
|
}
|
|
306
306
|
return fallbackLog[name];
|
|
307
307
|
};
|
|
308
308
|
var defaultLogger = null;
|
|
309
|
-
var setDefaultLogger = (
|
|
310
|
-
defaultLogger =
|
|
309
|
+
var setDefaultLogger = (logger13) => {
|
|
310
|
+
defaultLogger = logger13;
|
|
311
311
|
};
|
|
312
312
|
var resolveLogger = (explicitLogger) => {
|
|
313
313
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -334,8 +334,8 @@ var colorize = (text, color) => {
|
|
|
334
334
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
335
335
|
const name = prefix ? String(prefix) : "";
|
|
336
336
|
const dispatch = (methodName, icon, message, color) => {
|
|
337
|
-
const
|
|
338
|
-
const logFn = resolveLogMethod(
|
|
337
|
+
const logger13 = resolveLogger(explicitLogger);
|
|
338
|
+
const logFn = resolveLogMethod(logger13, methodName);
|
|
339
339
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
340
340
|
const line = formatLine(name, icon, message);
|
|
341
341
|
const coloredLine = colorize(line, color);
|
|
@@ -1260,15 +1260,89 @@ var Humanize = {
|
|
|
1260
1260
|
};
|
|
1261
1261
|
|
|
1262
1262
|
// src/launch.js
|
|
1263
|
+
var logger6 = createInternalLogger("Launch");
|
|
1264
|
+
var normalizeByPassDomains = (domains) => {
|
|
1265
|
+
if (!Array.isArray(domains)) return [];
|
|
1266
|
+
return domains.map((item) => String(item || "").trim()).filter(Boolean);
|
|
1267
|
+
};
|
|
1268
|
+
var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
|
|
1269
|
+
const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
|
|
1270
|
+
const proxyUrl = String(config.proxy_url || "").trim();
|
|
1271
|
+
const enableProxy = typeof config.enable_proxy === "boolean" ? config.enable_proxy : proxyUrl !== "";
|
|
1272
|
+
if (!enableProxy || !proxyUrl) {
|
|
1273
|
+
return { launchProxy: null, byPassDomains: [], enableProxy, proxyUrl };
|
|
1274
|
+
}
|
|
1275
|
+
const byPassDomains = normalizeByPassDomains(config.by_pass_domains);
|
|
1276
|
+
let parsedProxyUrl;
|
|
1277
|
+
parsedProxyUrl = new URL(proxyUrl);
|
|
1278
|
+
const launchProxy = {
|
|
1279
|
+
server: `${parsedProxyUrl.protocol}//${parsedProxyUrl.host}`
|
|
1280
|
+
};
|
|
1281
|
+
if (parsedProxyUrl.username) {
|
|
1282
|
+
launchProxy.username = decodeURIComponent(parsedProxyUrl.username);
|
|
1283
|
+
}
|
|
1284
|
+
if (parsedProxyUrl.password) {
|
|
1285
|
+
launchProxy.password = decodeURIComponent(parsedProxyUrl.password);
|
|
1286
|
+
}
|
|
1287
|
+
if (byPassDomains.length > 0) {
|
|
1288
|
+
launchProxy.bypass = byPassDomains.join(",");
|
|
1289
|
+
}
|
|
1290
|
+
return { launchProxy, byPassDomains, enableProxy, proxyUrl };
|
|
1291
|
+
};
|
|
1263
1292
|
var Launch = {
|
|
1264
|
-
getLaunchOptions(
|
|
1265
|
-
|
|
1293
|
+
getLaunchOptions(options = {}) {
|
|
1294
|
+
const normalizedOptions = Array.isArray(options) ? { customArgs: options } : options || {};
|
|
1295
|
+
const {
|
|
1296
|
+
customArgs = [],
|
|
1297
|
+
proxyConfiguration = {},
|
|
1298
|
+
log: logOptions = null
|
|
1299
|
+
} = normalizedOptions;
|
|
1300
|
+
const { launchProxy, byPassDomains, enableProxy, proxyUrl } = resolveProxyLaunchOptions(proxyConfiguration);
|
|
1301
|
+
const launchOptions = {
|
|
1266
1302
|
args: [
|
|
1267
1303
|
...AntiCheat.getLaunchArgs(),
|
|
1268
1304
|
...customArgs
|
|
1269
1305
|
],
|
|
1270
1306
|
ignoreDefaultArgs: ["--enable-automation"]
|
|
1271
1307
|
};
|
|
1308
|
+
if (launchProxy) {
|
|
1309
|
+
launchOptions.proxy = launchProxy;
|
|
1310
|
+
}
|
|
1311
|
+
const enableByPassLogger = Boolean(logOptions && logOptions.enable);
|
|
1312
|
+
if (enableByPassLogger && launchProxy) {
|
|
1313
|
+
logger6.info(
|
|
1314
|
+
`[\u4EE3\u7406\u5DF2\u542F\u7528] \u4EE3\u7406\u670D\u52A1=${launchProxy.server} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
|
|
1315
|
+
);
|
|
1316
|
+
} else if (enableByPassLogger && enableProxy && !launchProxy) {
|
|
1317
|
+
logger6.info(
|
|
1318
|
+
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A`
|
|
1319
|
+
);
|
|
1320
|
+
} else if (enableByPassLogger && !enableProxy && proxyUrl) {
|
|
1321
|
+
logger6.info(
|
|
1322
|
+
`[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E`
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
const onPageCreated = (page) => {
|
|
1326
|
+
if (!enableByPassLogger || byPassDomains.length === 0 || !page || typeof page.on !== "function") {
|
|
1327
|
+
return () => {
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
const domainSet = new Set(byPassDomains.map((domain) => domain.toLowerCase()));
|
|
1331
|
+
const requestHandler = (req) => {
|
|
1332
|
+
const requestUrl = req.url();
|
|
1333
|
+
let hostname = "";
|
|
1334
|
+
try {
|
|
1335
|
+
hostname = new URL(requestUrl).hostname.toLowerCase();
|
|
1336
|
+
} catch {
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
if (!domainSet.has(hostname)) return;
|
|
1340
|
+
logger6.info(`[\u76F4\u8FDE\u547D\u4E2D] \u57DF\u540D=${hostname} \u8D44\u6E90\u7C7B\u578B=${req.resourceType()} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
|
|
1341
|
+
};
|
|
1342
|
+
page.on("request", requestHandler);
|
|
1343
|
+
return () => page.off("request", requestHandler);
|
|
1344
|
+
};
|
|
1345
|
+
return { launchOptions, onPageCreated };
|
|
1272
1346
|
},
|
|
1273
1347
|
/**
|
|
1274
1348
|
* 推荐的 Fingerprint Generator 选项
|
|
@@ -1282,7 +1356,7 @@ var Launch = {
|
|
|
1282
1356
|
// src/live-view.js
|
|
1283
1357
|
var import_express = __toESM(require("express"), 1);
|
|
1284
1358
|
var import_apify = require("apify");
|
|
1285
|
-
var
|
|
1359
|
+
var logger7 = createInternalLogger("LiveView");
|
|
1286
1360
|
async function startLiveViewServer(liveViewKey) {
|
|
1287
1361
|
const app = (0, import_express.default)();
|
|
1288
1362
|
app.get("/", async (req, res) => {
|
|
@@ -1307,13 +1381,13 @@ async function startLiveViewServer(liveViewKey) {
|
|
|
1307
1381
|
</html>
|
|
1308
1382
|
`);
|
|
1309
1383
|
} catch (error) {
|
|
1310
|
-
|
|
1384
|
+
logger7.fail("Live View Server", error);
|
|
1311
1385
|
res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
|
|
1312
1386
|
}
|
|
1313
1387
|
});
|
|
1314
1388
|
const port = process.env.APIFY_CONTAINER_PORT || 4321;
|
|
1315
1389
|
app.listen(port, () => {
|
|
1316
|
-
|
|
1390
|
+
logger7.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
|
|
1317
1391
|
});
|
|
1318
1392
|
}
|
|
1319
1393
|
async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
@@ -1321,10 +1395,10 @@ async function takeLiveScreenshot(liveViewKey, page, logMessage) {
|
|
|
1321
1395
|
const buffer = await page.screenshot({ type: "png" });
|
|
1322
1396
|
await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
|
|
1323
1397
|
if (logMessage) {
|
|
1324
|
-
|
|
1398
|
+
logger7.info(`(\u622A\u56FE): ${logMessage}`);
|
|
1325
1399
|
}
|
|
1326
1400
|
} catch (e) {
|
|
1327
|
-
|
|
1401
|
+
logger7.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
|
|
1328
1402
|
}
|
|
1329
1403
|
}
|
|
1330
1404
|
var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
|
|
@@ -1343,7 +1417,7 @@ var LiveView = {
|
|
|
1343
1417
|
|
|
1344
1418
|
// src/captcha-monitor.js
|
|
1345
1419
|
var import_uuid = require("uuid");
|
|
1346
|
-
var
|
|
1420
|
+
var logger8 = createInternalLogger("Captcha");
|
|
1347
1421
|
function useCaptchaMonitor(page, options) {
|
|
1348
1422
|
const { domSelector, urlPattern, onDetected } = options;
|
|
1349
1423
|
if (!domSelector && !urlPattern) {
|
|
@@ -1415,7 +1489,7 @@ function useCaptchaMonitor(page, options) {
|
|
|
1415
1489
|
};
|
|
1416
1490
|
})();
|
|
1417
1491
|
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
1418
|
-
|
|
1492
|
+
logger8.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
|
|
1419
1493
|
cleanupFns.push(async () => {
|
|
1420
1494
|
try {
|
|
1421
1495
|
await page.evaluate((name) => {
|
|
@@ -1438,14 +1512,14 @@ function useCaptchaMonitor(page, options) {
|
|
|
1438
1512
|
}
|
|
1439
1513
|
};
|
|
1440
1514
|
page.on("framenavigated", frameHandler);
|
|
1441
|
-
|
|
1515
|
+
logger8.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
|
|
1442
1516
|
cleanupFns.push(async () => {
|
|
1443
1517
|
page.off("framenavigated", frameHandler);
|
|
1444
1518
|
});
|
|
1445
1519
|
}
|
|
1446
1520
|
return {
|
|
1447
1521
|
stop: async () => {
|
|
1448
|
-
|
|
1522
|
+
logger8.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
|
|
1449
1523
|
for (const fn of cleanupFns) {
|
|
1450
1524
|
await fn();
|
|
1451
1525
|
}
|
|
@@ -1460,7 +1534,7 @@ var Captcha = {
|
|
|
1460
1534
|
// src/sse.js
|
|
1461
1535
|
var import_https = __toESM(require("https"), 1);
|
|
1462
1536
|
var import_url = require("url");
|
|
1463
|
-
var
|
|
1537
|
+
var logger9 = createInternalLogger("Sse");
|
|
1464
1538
|
var Sse = {
|
|
1465
1539
|
/**
|
|
1466
1540
|
* 解析 SSE 流文本
|
|
@@ -1479,11 +1553,11 @@ var Sse = {
|
|
|
1479
1553
|
events.push(JSON.parse(jsonContent));
|
|
1480
1554
|
}
|
|
1481
1555
|
} catch (e) {
|
|
1482
|
-
|
|
1556
|
+
logger9.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
|
|
1483
1557
|
}
|
|
1484
1558
|
}
|
|
1485
1559
|
}
|
|
1486
|
-
|
|
1560
|
+
logger9.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
|
|
1487
1561
|
return events;
|
|
1488
1562
|
},
|
|
1489
1563
|
/**
|
|
@@ -1533,7 +1607,7 @@ var Sse = {
|
|
|
1533
1607
|
if (!autoUnroute) return;
|
|
1534
1608
|
if (unrouteRequested) return;
|
|
1535
1609
|
unrouteRequested = true;
|
|
1536
|
-
|
|
1610
|
+
logger9.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1537
1611
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1538
1612
|
});
|
|
1539
1613
|
};
|
|
@@ -1553,19 +1627,19 @@ var Sse = {
|
|
|
1553
1627
|
};
|
|
1554
1628
|
const routeHandler = async (route) => {
|
|
1555
1629
|
if (firstMatchOnly && hasMatchedOnce) {
|
|
1556
|
-
|
|
1630
|
+
logger9.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
|
|
1557
1631
|
route.continue().catch(() => {
|
|
1558
1632
|
});
|
|
1559
1633
|
return;
|
|
1560
1634
|
}
|
|
1561
1635
|
if (firstMatchOnly && !hasMatchedOnce) {
|
|
1562
1636
|
hasMatchedOnce = true;
|
|
1563
|
-
|
|
1637
|
+
logger9.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
|
|
1564
1638
|
page.unroute(urlPattern, routeHandler).catch(() => {
|
|
1565
1639
|
});
|
|
1566
1640
|
}
|
|
1567
1641
|
const request = route.request();
|
|
1568
|
-
|
|
1642
|
+
logger9.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
|
|
1569
1643
|
try {
|
|
1570
1644
|
const headers = await request.allHeaders();
|
|
1571
1645
|
const postData = request.postData();
|
|
@@ -1590,7 +1664,7 @@ var Sse = {
|
|
|
1590
1664
|
clearTimeout(initialTimer);
|
|
1591
1665
|
initialTimer = null;
|
|
1592
1666
|
}
|
|
1593
|
-
|
|
1667
|
+
logger9.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
|
|
1594
1668
|
}
|
|
1595
1669
|
chunks.push(chunk);
|
|
1596
1670
|
const textChunk = chunk.toString("utf-8");
|
|
@@ -1599,18 +1673,18 @@ var Sse = {
|
|
|
1599
1673
|
try {
|
|
1600
1674
|
onData(textChunk, safeResolve, accumulatedText);
|
|
1601
1675
|
} catch (e) {
|
|
1602
|
-
|
|
1676
|
+
logger9.fail(`onData \u9519\u8BEF`, e);
|
|
1603
1677
|
}
|
|
1604
1678
|
}
|
|
1605
1679
|
});
|
|
1606
1680
|
res.on("end", () => {
|
|
1607
|
-
|
|
1681
|
+
logger9.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
|
|
1608
1682
|
clearAllTimers();
|
|
1609
1683
|
if (onEnd) {
|
|
1610
1684
|
try {
|
|
1611
1685
|
onEnd(accumulatedText, safeResolve);
|
|
1612
1686
|
} catch (e) {
|
|
1613
|
-
|
|
1687
|
+
logger9.fail(`onEnd \u9519\u8BEF`, e);
|
|
1614
1688
|
}
|
|
1615
1689
|
} else if (!onData) {
|
|
1616
1690
|
safeResolve(accumulatedText);
|
|
@@ -1693,7 +1767,7 @@ var Sse = {
|
|
|
1693
1767
|
var import_got_scraping = require("got-scraping");
|
|
1694
1768
|
var import_http = require("http");
|
|
1695
1769
|
var import_https2 = require("https");
|
|
1696
|
-
var
|
|
1770
|
+
var logger10 = createInternalLogger("Interception");
|
|
1697
1771
|
var SHARED_HTTP_AGENT = new import_http.Agent({
|
|
1698
1772
|
keepAlive: true,
|
|
1699
1773
|
keepAliveMsecs: 15e3,
|
|
@@ -1901,9 +1975,9 @@ var Interception = {
|
|
|
1901
1975
|
const directRules = [];
|
|
1902
1976
|
if (hasDirectDomains) directRules.push(`\u76F4\u8FDE\u57DF\u540D: [${normalizedDirectDomains.length} \u4E2A]`);
|
|
1903
1977
|
if (hasDirectExtensions) directRules.push(`\u76F4\u8FDE\u6269\u5C55\u540D: [${normalizedDirectExtensions.join(", ")}]`);
|
|
1904
|
-
|
|
1978
|
+
logger10.start("setup", directRules.length > 0 ? `${directRules.join(" | ")} | \u5C4F\u853D: [${enabledCategories.join(", ")}]` : `\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F | \u5C4F\u853D: [${enabledCategories.join(", ")}]`);
|
|
1905
1979
|
if (!hasInterceptionRules) {
|
|
1906
|
-
|
|
1980
|
+
logger10.info("\u65E0\u547D\u4E2D\u89C4\u5219\uFF0C\u8DF3\u8FC7 page.route \u6CE8\u518C");
|
|
1907
1981
|
return;
|
|
1908
1982
|
}
|
|
1909
1983
|
const directRouteHandler = async (route) => {
|
|
@@ -1947,7 +2021,7 @@ var Interception = {
|
|
|
1947
2021
|
delete resHeaders["transfer-encoding"];
|
|
1948
2022
|
delete resHeaders["connection"];
|
|
1949
2023
|
delete resHeaders["keep-alive"];
|
|
1950
|
-
isSilent ?
|
|
2024
|
+
isSilent ? logger10.debug(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`) : logger10.info(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`);
|
|
1951
2025
|
await safeFulfill(route, {
|
|
1952
2026
|
status: response.statusCode,
|
|
1953
2027
|
headers: resHeaders,
|
|
@@ -1958,7 +2032,7 @@ var Interception = {
|
|
|
1958
2032
|
const isTimeout = err?.code === "ETIMEDOUT" || message.toLowerCase().includes("timeout");
|
|
1959
2033
|
const action = fallbackToProxy ? "\u56DE\u9000\u4EE3\u7406" : "\u5DF2\u653E\u5F03";
|
|
1960
2034
|
const reason = isTimeout ? `\u8D85\u65F6(${DirectConfig.directTimeout}s)` : `\u5F02\u5E38: ${message}`;
|
|
1961
|
-
|
|
2035
|
+
logger10.warn(`\u76F4\u8FDE${reason}\uFF0C${action}`);
|
|
1962
2036
|
if (fallbackToProxy) {
|
|
1963
2037
|
await safeContinue(route);
|
|
1964
2038
|
} else {
|
|
@@ -2032,7 +2106,7 @@ function escapeRegex(value) {
|
|
|
2032
2106
|
|
|
2033
2107
|
// src/mutation.js
|
|
2034
2108
|
var import_uuid2 = require("uuid");
|
|
2035
|
-
var
|
|
2109
|
+
var logger11 = createInternalLogger("Mutation");
|
|
2036
2110
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
2037
2111
|
Added: "added",
|
|
2038
2112
|
Changed: "changed",
|
|
@@ -2065,14 +2139,14 @@ var Mutation = {
|
|
|
2065
2139
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
2066
2140
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
2067
2141
|
const onMutation = options.onMutation;
|
|
2068
|
-
|
|
2142
|
+
logger11.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
2069
2143
|
if (initialTimeout > 0) {
|
|
2070
2144
|
const selectorQuery = selectorList.join(",");
|
|
2071
2145
|
try {
|
|
2072
2146
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
2073
|
-
|
|
2147
|
+
logger11.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
2074
2148
|
} catch (e) {
|
|
2075
|
-
|
|
2149
|
+
logger11.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
2076
2150
|
throw e;
|
|
2077
2151
|
}
|
|
2078
2152
|
}
|
|
@@ -2088,7 +2162,7 @@ var Mutation = {
|
|
|
2088
2162
|
return "__CONTINUE__";
|
|
2089
2163
|
}
|
|
2090
2164
|
});
|
|
2091
|
-
|
|
2165
|
+
logger11.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
2092
2166
|
} catch (e) {
|
|
2093
2167
|
}
|
|
2094
2168
|
}
|
|
@@ -2203,9 +2277,9 @@ var Mutation = {
|
|
|
2203
2277
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
2204
2278
|
);
|
|
2205
2279
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
2206
|
-
|
|
2280
|
+
logger11.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
2207
2281
|
}
|
|
2208
|
-
|
|
2282
|
+
logger11.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
2209
2283
|
return result;
|
|
2210
2284
|
},
|
|
2211
2285
|
/**
|
|
@@ -2225,7 +2299,7 @@ var Mutation = {
|
|
|
2225
2299
|
const onMutation = options.onMutation;
|
|
2226
2300
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
2227
2301
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
2228
|
-
|
|
2302
|
+
logger11.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
2229
2303
|
const monitorKey = generateKey("pk_mon");
|
|
2230
2304
|
const callbackName = generateKey("pk_mon_cb");
|
|
2231
2305
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2368,7 +2442,7 @@ var Mutation = {
|
|
|
2368
2442
|
return total;
|
|
2369
2443
|
};
|
|
2370
2444
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
2371
|
-
|
|
2445
|
+
logger11.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2372
2446
|
return {
|
|
2373
2447
|
stop: async () => {
|
|
2374
2448
|
let totalMutations = 0;
|
|
@@ -2381,7 +2455,7 @@ var Mutation = {
|
|
|
2381
2455
|
}, cleanerName);
|
|
2382
2456
|
} catch (e) {
|
|
2383
2457
|
}
|
|
2384
|
-
|
|
2458
|
+
logger11.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2385
2459
|
return { totalMutations };
|
|
2386
2460
|
}
|
|
2387
2461
|
};
|
|
@@ -3202,7 +3276,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
3202
3276
|
};
|
|
3203
3277
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
3204
3278
|
var Logger = {
|
|
3205
|
-
setLogger: (
|
|
3279
|
+
setLogger: (logger13) => setDefaultLogger(logger13),
|
|
3206
3280
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
3207
3281
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
3208
3282
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -3210,15 +3284,15 @@ var Logger = {
|
|
|
3210
3284
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
3211
3285
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
3212
3286
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
3213
|
-
useTemplate: (
|
|
3214
|
-
if (
|
|
3287
|
+
useTemplate: (logger13) => {
|
|
3288
|
+
if (logger13) return createTemplateLogger(createBaseLogger("", logger13));
|
|
3215
3289
|
return createTemplateLogger();
|
|
3216
3290
|
}
|
|
3217
3291
|
};
|
|
3218
3292
|
|
|
3219
3293
|
// src/share.js
|
|
3220
3294
|
var import_delay3 = __toESM(require("delay"), 1);
|
|
3221
|
-
var
|
|
3295
|
+
var logger12 = createInternalLogger("Share");
|
|
3222
3296
|
var DEFAULT_TIMEOUT_MS = 50 * 1e3;
|
|
3223
3297
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
3224
3298
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -3338,7 +3412,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
3338
3412
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
3339
3413
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
3340
3414
|
let matched = false;
|
|
3341
|
-
|
|
3415
|
+
logger12.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
3342
3416
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
3343
3417
|
mode,
|
|
3344
3418
|
onMutation: (context = {}) => {
|
|
@@ -3356,12 +3430,12 @@ ${text}`;
|
|
|
3356
3430
|
});
|
|
3357
3431
|
}
|
|
3358
3432
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
3359
|
-
|
|
3433
|
+
logger12.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
3360
3434
|
}
|
|
3361
3435
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
3362
3436
|
if (!candidate) return;
|
|
3363
3437
|
matched = true;
|
|
3364
|
-
|
|
3438
|
+
logger12.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
3365
3439
|
if (onMatch) {
|
|
3366
3440
|
onMatch({
|
|
3367
3441
|
link: candidate,
|
|
@@ -3377,7 +3451,7 @@ ${text}`;
|
|
|
3377
3451
|
return {
|
|
3378
3452
|
stop: async () => {
|
|
3379
3453
|
const result = await monitor.stop();
|
|
3380
|
-
|
|
3454
|
+
logger12.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
3381
3455
|
return result;
|
|
3382
3456
|
}
|
|
3383
3457
|
};
|
|
@@ -3417,8 +3491,8 @@ var Share = {
|
|
|
3417
3491
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
3418
3492
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
3419
3493
|
}
|
|
3420
|
-
|
|
3421
|
-
|
|
3494
|
+
logger12.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
3495
|
+
logger12.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
3422
3496
|
const stats = {
|
|
3423
3497
|
actionTimedOut: false,
|
|
3424
3498
|
domMutationCount: 0,
|
|
@@ -3443,7 +3517,7 @@ var Share = {
|
|
|
3443
3517
|
link: validated,
|
|
3444
3518
|
payloadText: String(payloadText || "")
|
|
3445
3519
|
};
|
|
3446
|
-
|
|
3520
|
+
logger12.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
3447
3521
|
return true;
|
|
3448
3522
|
};
|
|
3449
3523
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -3478,7 +3552,7 @@ var Share = {
|
|
|
3478
3552
|
try {
|
|
3479
3553
|
await monitor.stop();
|
|
3480
3554
|
} catch (error) {
|
|
3481
|
-
|
|
3555
|
+
logger12.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
3482
3556
|
}
|
|
3483
3557
|
};
|
|
3484
3558
|
const onResponse = async (response) => {
|
|
@@ -3491,29 +3565,29 @@ var Share = {
|
|
|
3491
3565
|
stats.responseSampleUrls.push(url);
|
|
3492
3566
|
}
|
|
3493
3567
|
if (stats.responseObserved <= 5) {
|
|
3494
|
-
|
|
3568
|
+
logger12.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
3495
3569
|
}
|
|
3496
3570
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
3497
3571
|
stats.responseMatched += 1;
|
|
3498
3572
|
stats.lastMatchedUrl = url;
|
|
3499
|
-
|
|
3573
|
+
logger12.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
3500
3574
|
const text = await response.text();
|
|
3501
3575
|
const hit = resolveResponseCandidate(text);
|
|
3502
3576
|
if (!hit?.link) {
|
|
3503
3577
|
if (stats.responseMatched <= 3) {
|
|
3504
|
-
|
|
3578
|
+
logger12.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
3505
3579
|
}
|
|
3506
3580
|
return;
|
|
3507
3581
|
}
|
|
3508
3582
|
stats.responseResolved += 1;
|
|
3509
|
-
|
|
3583
|
+
logger12.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
3510
3584
|
setCandidate("response", hit.link, hit.payloadText);
|
|
3511
3585
|
} catch (error) {
|
|
3512
|
-
|
|
3586
|
+
logger12.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
3513
3587
|
}
|
|
3514
3588
|
};
|
|
3515
3589
|
if (share.mode === "dom") {
|
|
3516
|
-
|
|
3590
|
+
logger12.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
3517
3591
|
domMonitor = await createDomShareMonitor(page, {
|
|
3518
3592
|
prefix: share.prefix,
|
|
3519
3593
|
selectors: domSelectors,
|
|
@@ -3528,14 +3602,14 @@ var Share = {
|
|
|
3528
3602
|
});
|
|
3529
3603
|
}
|
|
3530
3604
|
if (share.mode === "response") {
|
|
3531
|
-
|
|
3605
|
+
logger12.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
3532
3606
|
page.on("response", onResponse);
|
|
3533
3607
|
}
|
|
3534
3608
|
const deadline = Date.now() + timeoutMs;
|
|
3535
3609
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
3536
3610
|
try {
|
|
3537
3611
|
const actionTimeout = getRemainingMs();
|
|
3538
|
-
|
|
3612
|
+
logger12.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
3539
3613
|
if (actionTimeout > 0) {
|
|
3540
3614
|
let timer = null;
|
|
3541
3615
|
let actionError = null;
|
|
@@ -3549,21 +3623,21 @@ var Share = {
|
|
|
3549
3623
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
3550
3624
|
if (timer) clearTimeout(timer);
|
|
3551
3625
|
if (actionResult === "__ACTION_ERROR__") {
|
|
3552
|
-
|
|
3626
|
+
logger12.fail("captureLink.performActions", actionError);
|
|
3553
3627
|
throw actionError;
|
|
3554
3628
|
}
|
|
3555
3629
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
3556
3630
|
stats.actionTimedOut = true;
|
|
3557
|
-
|
|
3631
|
+
logger12.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
3558
3632
|
} else {
|
|
3559
|
-
|
|
3633
|
+
logger12.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
3560
3634
|
}
|
|
3561
3635
|
}
|
|
3562
3636
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
3563
3637
|
while (true) {
|
|
3564
3638
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
3565
3639
|
if (selected?.link) {
|
|
3566
|
-
|
|
3640
|
+
logger12.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
3567
3641
|
return {
|
|
3568
3642
|
link: selected.link,
|
|
3569
3643
|
payloadText: selected.payloadText,
|
|
@@ -3575,7 +3649,7 @@ var Share = {
|
|
|
3575
3649
|
if (remaining <= 0) break;
|
|
3576
3650
|
const now = Date.now();
|
|
3577
3651
|
if (now >= nextProgressLogTs) {
|
|
3578
|
-
|
|
3652
|
+
logger12.info(
|
|
3579
3653
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
3580
3654
|
);
|
|
3581
3655
|
nextProgressLogTs = now + 5e3;
|
|
@@ -3583,11 +3657,11 @@ var Share = {
|
|
|
3583
3657
|
await (0, import_delay3.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
3584
3658
|
}
|
|
3585
3659
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
3586
|
-
|
|
3660
|
+
logger12.warning(
|
|
3587
3661
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
3588
3662
|
);
|
|
3589
3663
|
}
|
|
3590
|
-
|
|
3664
|
+
logger12.warning(
|
|
3591
3665
|
`captureLink \u8D85\u65F6\u672A\u62FF\u5230\u94FE\u63A5: mode=${share.mode}, actionTimedOut=${stats.actionTimedOut}, domMutationCount=${stats.domMutationCount}, responseObserved=${stats.responseObserved}, responseMatched=${stats.responseMatched}, lastMatchedUrl=${stats.lastMatchedUrl || "none"}`
|
|
3592
3666
|
);
|
|
3593
3667
|
return {
|
|
@@ -3599,7 +3673,7 @@ var Share = {
|
|
|
3599
3673
|
} finally {
|
|
3600
3674
|
if (share.mode === "response") {
|
|
3601
3675
|
page.off("response", onResponse);
|
|
3602
|
-
|
|
3676
|
+
logger12.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
3603
3677
|
}
|
|
3604
3678
|
await stopDomMonitor();
|
|
3605
3679
|
}
|