@skrillex1224/playwright-toolkit 2.1.140 → 2.1.143
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/dist/browser.js +7 -4
- package/dist/browser.js.map +2 -2
- package/dist/index.cjs +54 -393
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +54 -393
- package/dist/index.js.map +4 -4
- package/index.d.ts +0 -81
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -212,14 +212,17 @@ var ActorInfo = {
|
|
|
212
212
|
}),
|
|
213
213
|
erineaisearch: createActorInfo({
|
|
214
214
|
key: "erineaisearch",
|
|
215
|
-
name: "\u767E\u5EA6AI\u641C
|
|
215
|
+
name: "\u767E\u5EA6AI\u641C",
|
|
216
216
|
domain: "www.baidu.com",
|
|
217
217
|
path: "/s",
|
|
218
|
-
// 暂未使用
|
|
219
218
|
share: {
|
|
220
|
-
mode: "
|
|
219
|
+
mode: "response",
|
|
221
220
|
prefix: "",
|
|
222
|
-
xurl: [
|
|
221
|
+
xurl: [
|
|
222
|
+
"/aichat/api/shortURL",
|
|
223
|
+
"data",
|
|
224
|
+
"short_url"
|
|
225
|
+
]
|
|
223
226
|
}
|
|
224
227
|
}),
|
|
225
228
|
yuanbao: createActorInfo({
|
|
@@ -296,18 +299,18 @@ var fallbackLog = {
|
|
|
296
299
|
error: (...args) => console.error(...args),
|
|
297
300
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
298
301
|
};
|
|
299
|
-
var resolveLogMethod = (
|
|
300
|
-
if (
|
|
301
|
-
return
|
|
302
|
+
var resolveLogMethod = (logger12, name) => {
|
|
303
|
+
if (logger12 && typeof logger12[name] === "function") {
|
|
304
|
+
return logger12[name].bind(logger12);
|
|
302
305
|
}
|
|
303
|
-
if (name === "warning" &&
|
|
304
|
-
return
|
|
306
|
+
if (name === "warning" && logger12 && typeof logger12.warn === "function") {
|
|
307
|
+
return logger12.warn.bind(logger12);
|
|
305
308
|
}
|
|
306
309
|
return fallbackLog[name];
|
|
307
310
|
};
|
|
308
311
|
var defaultLogger = null;
|
|
309
|
-
var setDefaultLogger = (
|
|
310
|
-
defaultLogger =
|
|
312
|
+
var setDefaultLogger = (logger12) => {
|
|
313
|
+
defaultLogger = logger12;
|
|
311
314
|
};
|
|
312
315
|
var resolveLogger = (explicitLogger) => {
|
|
313
316
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -334,8 +337,8 @@ var colorize = (text, color) => {
|
|
|
334
337
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
335
338
|
const name = prefix ? String(prefix) : "";
|
|
336
339
|
const dispatch = (methodName, icon, message, color) => {
|
|
337
|
-
const
|
|
338
|
-
const logFn = resolveLogMethod(
|
|
340
|
+
const logger12 = resolveLogger(explicitLogger);
|
|
341
|
+
const logFn = resolveLogMethod(logger12, methodName);
|
|
339
342
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
340
343
|
const line = formatLine(name, icon, message);
|
|
341
344
|
const coloredLine = colorize(line, color);
|
|
@@ -1763,350 +1766,9 @@ var Sse = {
|
|
|
1763
1766
|
}
|
|
1764
1767
|
};
|
|
1765
1768
|
|
|
1766
|
-
// src/interception.js
|
|
1767
|
-
var import_got_scraping = require("got-scraping");
|
|
1768
|
-
var import_http = require("http");
|
|
1769
|
-
var import_https2 = require("https");
|
|
1770
|
-
var logger10 = createInternalLogger("Interception");
|
|
1771
|
-
var SHARED_HTTP_AGENT = new import_http.Agent({
|
|
1772
|
-
keepAlive: true,
|
|
1773
|
-
keepAliveMsecs: 15e3,
|
|
1774
|
-
maxSockets: 30,
|
|
1775
|
-
maxFreeSockets: 10
|
|
1776
|
-
});
|
|
1777
|
-
var SHARED_HTTPS_AGENT = new import_https2.Agent({
|
|
1778
|
-
keepAlive: true,
|
|
1779
|
-
keepAliveMsecs: 15e3,
|
|
1780
|
-
maxSockets: 30,
|
|
1781
|
-
maxFreeSockets: 10,
|
|
1782
|
-
rejectUnauthorized: false
|
|
1783
|
-
});
|
|
1784
|
-
var ARCHIVE_EXTENSIONS = [".7z", ".zip", ".rar", ".gz", ".bz2", ".tar", ".zst"];
|
|
1785
|
-
var EXECUTABLE_EXTENSIONS = [".exe", ".apk", ".bin", ".dmg", ".jar", ".class"];
|
|
1786
|
-
var DOCUMENT_EXTENSIONS = [".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".csv"];
|
|
1787
|
-
var IMAGE_EXTENSIONS = [
|
|
1788
|
-
".jpg",
|
|
1789
|
-
".jpeg",
|
|
1790
|
-
".png",
|
|
1791
|
-
".gif",
|
|
1792
|
-
".bmp",
|
|
1793
|
-
".ico",
|
|
1794
|
-
".svg",
|
|
1795
|
-
".svgz",
|
|
1796
|
-
".webp",
|
|
1797
|
-
".avif",
|
|
1798
|
-
".pis",
|
|
1799
|
-
".pict",
|
|
1800
|
-
".tif",
|
|
1801
|
-
".tiff",
|
|
1802
|
-
".eps",
|
|
1803
|
-
".ejs",
|
|
1804
|
-
".eot"
|
|
1805
|
-
];
|
|
1806
|
-
var MEDIA_EXTENSIONS = [".mp3", ".mp4", ".avi", ".mkv", ".webm", ".midi", ".mid", ".ogg", ".flac", ".swf"];
|
|
1807
|
-
var FONT_EXTENSIONS = [".woff", ".woff2", ".ttf", ".otf"];
|
|
1808
|
-
var CSS_EXTENSIONS = [".css"];
|
|
1809
|
-
var JS_EXTENSIONS = [".js"];
|
|
1810
|
-
var OTHER_EXTENSIONS = [".ps", ".iso"];
|
|
1811
|
-
var DirectConfig = {
|
|
1812
|
-
/** 直连请求超时时间(秒) */
|
|
1813
|
-
directTimeout: 12,
|
|
1814
|
-
/** 静默扩展名:这些扩展名的直连成功日志用 debug 级别 */
|
|
1815
|
-
silentExtensions: JS_EXTENSIONS
|
|
1816
|
-
};
|
|
1817
|
-
var DEFAULT_BLOCKING_CONFIG = {
|
|
1818
|
-
/** 屏蔽压缩包 */
|
|
1819
|
-
blockArchive: true,
|
|
1820
|
-
/** 屏蔽可执行文件 */
|
|
1821
|
-
blockExecutable: true,
|
|
1822
|
-
/** 屏蔽办公文档 */
|
|
1823
|
-
blockDocument: true,
|
|
1824
|
-
/** 屏蔽图片 */
|
|
1825
|
-
blockImage: true,
|
|
1826
|
-
/** 屏蔽音视频 */
|
|
1827
|
-
blockMedia: true,
|
|
1828
|
-
/** 屏蔽字体 */
|
|
1829
|
-
blockFont: true,
|
|
1830
|
-
/** 屏蔽 CSS (注意:可能影响页面视觉效果) */
|
|
1831
|
-
blockCss: false,
|
|
1832
|
-
/** 屏蔽其他资源 */
|
|
1833
|
-
blockOther: true
|
|
1834
|
-
};
|
|
1835
|
-
var DEFAULT_DIRECT_CONFIG = {
|
|
1836
|
-
/** 直连域名 */
|
|
1837
|
-
domains: [],
|
|
1838
|
-
/** 直连压缩包 */
|
|
1839
|
-
directAllArchive: false,
|
|
1840
|
-
/** 直连可执行文件 */
|
|
1841
|
-
directAllExecutable: false,
|
|
1842
|
-
/** 直连办公文档 */
|
|
1843
|
-
directAllDocument: false,
|
|
1844
|
-
/** 直连图片 */
|
|
1845
|
-
directAllImage: false,
|
|
1846
|
-
/** 直连音视频 */
|
|
1847
|
-
directAllMedia: false,
|
|
1848
|
-
/** 直连字体 */
|
|
1849
|
-
directAllFont: false,
|
|
1850
|
-
/** 直连 CSS */
|
|
1851
|
-
directAllCss: false,
|
|
1852
|
-
/** 直连 JS */
|
|
1853
|
-
directAllJs: false,
|
|
1854
|
-
/** 直连其他资源 */
|
|
1855
|
-
directAllOther: false
|
|
1856
|
-
};
|
|
1857
|
-
var SHARED_GOT_OPTIONS = {
|
|
1858
|
-
http2: false,
|
|
1859
|
-
// 禁用 HTTP2 避免在拦截场景下的握手兼容性问题
|
|
1860
|
-
retry: { limit: 0 },
|
|
1861
|
-
// 让 Playwright 或外层逻辑处理重试
|
|
1862
|
-
throwHttpErrors: false
|
|
1863
|
-
// 404/500 等错误不抛出异常,直接透传给浏览器
|
|
1864
|
-
};
|
|
1865
|
-
var Interception = {
|
|
1866
|
-
/**
|
|
1867
|
-
* 根据配置生成需要屏蔽的扩展名列表
|
|
1868
|
-
*
|
|
1869
|
-
* @param {Object} [config] - 屏蔽配置
|
|
1870
|
-
* @returns {string[]} 需要屏蔽的扩展名列表
|
|
1871
|
-
*/
|
|
1872
|
-
getBlockedExtensions(config = {}) {
|
|
1873
|
-
const mergedConfig = { ...DEFAULT_BLOCKING_CONFIG, ...config };
|
|
1874
|
-
const extensions = [];
|
|
1875
|
-
if (mergedConfig.blockArchive) extensions.push(...ARCHIVE_EXTENSIONS);
|
|
1876
|
-
if (mergedConfig.blockExecutable) extensions.push(...EXECUTABLE_EXTENSIONS);
|
|
1877
|
-
if (mergedConfig.blockDocument) extensions.push(...DOCUMENT_EXTENSIONS);
|
|
1878
|
-
if (mergedConfig.blockImage) extensions.push(...IMAGE_EXTENSIONS);
|
|
1879
|
-
if (mergedConfig.blockMedia) extensions.push(...MEDIA_EXTENSIONS);
|
|
1880
|
-
if (mergedConfig.blockFont) extensions.push(...FONT_EXTENSIONS);
|
|
1881
|
-
if (mergedConfig.blockCss) extensions.push(...CSS_EXTENSIONS);
|
|
1882
|
-
if (mergedConfig.blockOther) extensions.push(...OTHER_EXTENSIONS);
|
|
1883
|
-
return [...new Set(extensions)];
|
|
1884
|
-
},
|
|
1885
|
-
/**
|
|
1886
|
-
* 获取所有可用的扩展名分类信息
|
|
1887
|
-
*
|
|
1888
|
-
* @returns {Object} 分类信息
|
|
1889
|
-
*/
|
|
1890
|
-
getExtensionCategories() {
|
|
1891
|
-
return {
|
|
1892
|
-
archive: { name: "\u538B\u7F29\u5305", extensions: ARCHIVE_EXTENSIONS },
|
|
1893
|
-
executable: { name: "\u53EF\u6267\u884C\u6587\u4EF6", extensions: EXECUTABLE_EXTENSIONS },
|
|
1894
|
-
document: { name: "\u529E\u516C\u6587\u6863", extensions: DOCUMENT_EXTENSIONS },
|
|
1895
|
-
image: { name: "\u56FE\u7247", extensions: IMAGE_EXTENSIONS },
|
|
1896
|
-
media: { name: "\u97F3\u89C6\u9891", extensions: MEDIA_EXTENSIONS },
|
|
1897
|
-
font: { name: "\u5B57\u4F53", extensions: FONT_EXTENSIONS },
|
|
1898
|
-
css: { name: "CSS \u6837\u5F0F", extensions: CSS_EXTENSIONS },
|
|
1899
|
-
other: { name: "\u5176\u4ED6\u8D44\u6E90", extensions: OTHER_EXTENSIONS }
|
|
1900
|
-
};
|
|
1901
|
-
},
|
|
1902
|
-
/**
|
|
1903
|
-
* 根据配置生成需要直连的扩展名列表
|
|
1904
|
-
*
|
|
1905
|
-
* @param {Object} [config] - 直连扩展名配置
|
|
1906
|
-
* @returns {string[]} 需要直连的扩展名列表
|
|
1907
|
-
*/
|
|
1908
|
-
getDirectExtensions(config = {}) {
|
|
1909
|
-
const mergedConfig = { ...DEFAULT_DIRECT_CONFIG, ...config };
|
|
1910
|
-
const extensions = [];
|
|
1911
|
-
if (mergedConfig.directAllArchive) extensions.push(...ARCHIVE_EXTENSIONS);
|
|
1912
|
-
if (mergedConfig.directAllExecutable) extensions.push(...EXECUTABLE_EXTENSIONS);
|
|
1913
|
-
if (mergedConfig.directAllDocument) extensions.push(...DOCUMENT_EXTENSIONS);
|
|
1914
|
-
if (mergedConfig.directAllImage) extensions.push(...IMAGE_EXTENSIONS);
|
|
1915
|
-
if (mergedConfig.directAllMedia) extensions.push(...MEDIA_EXTENSIONS);
|
|
1916
|
-
if (mergedConfig.directAllFont) extensions.push(...FONT_EXTENSIONS);
|
|
1917
|
-
if (mergedConfig.directAllCss) extensions.push(...CSS_EXTENSIONS);
|
|
1918
|
-
if (mergedConfig.directAllJs) extensions.push(...JS_EXTENSIONS);
|
|
1919
|
-
if (mergedConfig.directAllOther) extensions.push(...OTHER_EXTENSIONS);
|
|
1920
|
-
return [...new Set(extensions)];
|
|
1921
|
-
},
|
|
1922
|
-
/**
|
|
1923
|
-
* 设置网络拦截规则(资源屏蔽 + CDN 直连)
|
|
1924
|
-
*
|
|
1925
|
-
* @param {import('playwright').Page} page - Playwright Page 对象
|
|
1926
|
-
* @param {Object} [options] - 配置选项
|
|
1927
|
-
* @param {string[]} [options.directDomains] - [已过时] 需要直连的域名列表,请改用 directConfig.domains
|
|
1928
|
-
* @param {Object} [options.directConfig] - 直连配置(参考 blockingConfig),支持 domains/directAllXxx 系列开关
|
|
1929
|
-
* @param {Object} [options.blockingConfig] - 资源屏蔽配置
|
|
1930
|
-
* @param {boolean} [options.fallbackToProxy] - 直连失败时是否回退到代理(默认 true)
|
|
1931
|
-
* @returns {Promise<void>}
|
|
1932
|
-
*/
|
|
1933
|
-
async setup(page, options = {}) {
|
|
1934
|
-
const {
|
|
1935
|
-
directDomains = [],
|
|
1936
|
-
directConfig = {},
|
|
1937
|
-
blockingConfig = {},
|
|
1938
|
-
fallbackToProxy = true
|
|
1939
|
-
} = options;
|
|
1940
|
-
const mergedBlockingConfig = { ...DEFAULT_BLOCKING_CONFIG, ...blockingConfig };
|
|
1941
|
-
const mergedDirectConfig = { ...DEFAULT_DIRECT_CONFIG, ...directConfig };
|
|
1942
|
-
const blockedExtensions = this.getBlockedExtensions(mergedBlockingConfig);
|
|
1943
|
-
const configuredDirectExtensions = this.getDirectExtensions(mergedDirectConfig);
|
|
1944
|
-
const normalizedDirectDomains = Array.from(
|
|
1945
|
-
new Set(
|
|
1946
|
-
[...directDomains, ...mergedDirectConfig.domains || []].map((domain) => String(domain || "").toLowerCase().trim()).filter(Boolean)
|
|
1947
|
-
)
|
|
1948
|
-
);
|
|
1949
|
-
const hasDirectDomains = normalizedDirectDomains.length > 0;
|
|
1950
|
-
const normalizedDirectExtensions = Array.from(
|
|
1951
|
-
new Set(
|
|
1952
|
-
configuredDirectExtensions.map((ext) => String(ext || "").toLowerCase().trim()).filter(Boolean).map((ext) => ext.startsWith(".") ? ext : `.${ext}`)
|
|
1953
|
-
)
|
|
1954
|
-
);
|
|
1955
|
-
const hasDirectExtensions = normalizedDirectExtensions.length > 0;
|
|
1956
|
-
const blockedExtensionsSet = new Set(blockedExtensions);
|
|
1957
|
-
const directOnlyExtensions = normalizedDirectExtensions.filter((ext) => !blockedExtensionsSet.has(ext));
|
|
1958
|
-
const directRouteMatchers = [
|
|
1959
|
-
createDomainsRegex(normalizedDirectDomains),
|
|
1960
|
-
createExtensionsRegex(directOnlyExtensions)
|
|
1961
|
-
].filter(Boolean);
|
|
1962
|
-
const blockRouteMatchers = [createExtensionsRegex(blockedExtensions)].filter(Boolean);
|
|
1963
|
-
const hasDirectRules = directRouteMatchers.length > 0;
|
|
1964
|
-
const hasBlockRules = blockRouteMatchers.length > 0;
|
|
1965
|
-
const hasInterceptionRules = hasDirectRules || hasBlockRules;
|
|
1966
|
-
const enabledCategories = [];
|
|
1967
|
-
if (mergedBlockingConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
|
|
1968
|
-
if (mergedBlockingConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
|
|
1969
|
-
if (mergedBlockingConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
|
|
1970
|
-
if (mergedBlockingConfig.blockImage) enabledCategories.push("\u56FE\u7247");
|
|
1971
|
-
if (mergedBlockingConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
|
|
1972
|
-
if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
|
|
1973
|
-
if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
|
|
1974
|
-
if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
|
|
1975
|
-
const directRules = [];
|
|
1976
|
-
if (hasDirectDomains) directRules.push(`\u76F4\u8FDE\u57DF\u540D: [${normalizedDirectDomains.length} \u4E2A]`);
|
|
1977
|
-
if (hasDirectExtensions) directRules.push(`\u76F4\u8FDE\u6269\u5C55\u540D: [${normalizedDirectExtensions.join(", ")}]`);
|
|
1978
|
-
logger10.start("setup", directRules.length > 0 ? `${directRules.join(" | ")} | \u5C4F\u853D: [${enabledCategories.join(", ")}]` : `\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F | \u5C4F\u853D: [${enabledCategories.join(", ")}]`);
|
|
1979
|
-
if (!hasInterceptionRules) {
|
|
1980
|
-
logger10.info("\u65E0\u547D\u4E2D\u89C4\u5219\uFF0C\u8DF3\u8FC7 page.route \u6CE8\u518C");
|
|
1981
|
-
return;
|
|
1982
|
-
}
|
|
1983
|
-
const directRouteHandler = async (route) => {
|
|
1984
|
-
try {
|
|
1985
|
-
const request = route.request();
|
|
1986
|
-
const url = request.url();
|
|
1987
|
-
const urlLower = url.toLowerCase();
|
|
1988
|
-
const urlPath = urlLower.split("?")[0];
|
|
1989
|
-
const isSilent = DirectConfig.silentExtensions.some((ext) => urlPath.endsWith(ext));
|
|
1990
|
-
const reqHeaders = await request.allHeaders();
|
|
1991
|
-
delete reqHeaders["host"];
|
|
1992
|
-
const method = request.method();
|
|
1993
|
-
const postData = method !== "GET" && method !== "HEAD" ? request.postDataBuffer() : void 0;
|
|
1994
|
-
const response = await (0, import_got_scraping.gotScraping)({
|
|
1995
|
-
...SHARED_GOT_OPTIONS,
|
|
1996
|
-
// 应用通用配置
|
|
1997
|
-
url,
|
|
1998
|
-
method,
|
|
1999
|
-
headers: reqHeaders,
|
|
2000
|
-
body: postData,
|
|
2001
|
-
responseType: "buffer",
|
|
2002
|
-
// 强制获取 Buffer
|
|
2003
|
-
// 使用共享的 Agent 单例(keepAlive: false,不会池化连接)
|
|
2004
|
-
agent: {
|
|
2005
|
-
http: SHARED_HTTP_AGENT,
|
|
2006
|
-
https: SHARED_HTTPS_AGENT
|
|
2007
|
-
},
|
|
2008
|
-
// 超时时间
|
|
2009
|
-
timeout: { request: DirectConfig.directTimeout * 1e3 }
|
|
2010
|
-
});
|
|
2011
|
-
const resHeaders = {};
|
|
2012
|
-
for (const [key, value] of Object.entries(response.headers)) {
|
|
2013
|
-
if (Array.isArray(value)) {
|
|
2014
|
-
resHeaders[key] = value.join(", ");
|
|
2015
|
-
} else if (value) {
|
|
2016
|
-
resHeaders[key] = String(value);
|
|
2017
|
-
}
|
|
2018
|
-
}
|
|
2019
|
-
delete resHeaders["content-encoding"];
|
|
2020
|
-
delete resHeaders["content-length"];
|
|
2021
|
-
delete resHeaders["transfer-encoding"];
|
|
2022
|
-
delete resHeaders["connection"];
|
|
2023
|
-
delete resHeaders["keep-alive"];
|
|
2024
|
-
isSilent ? logger10.debug(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`) : logger10.info(`\u76F4\u8FDE\u6210\u529F: ${urlPath}`);
|
|
2025
|
-
await safeFulfill(route, {
|
|
2026
|
-
status: response.statusCode,
|
|
2027
|
-
headers: resHeaders,
|
|
2028
|
-
body: response.body
|
|
2029
|
-
});
|
|
2030
|
-
} catch (err) {
|
|
2031
|
-
const message = String(err?.message || "");
|
|
2032
|
-
const isTimeout = err?.code === "ETIMEDOUT" || message.toLowerCase().includes("timeout");
|
|
2033
|
-
const action = fallbackToProxy ? "\u56DE\u9000\u4EE3\u7406" : "\u5DF2\u653E\u5F03";
|
|
2034
|
-
const reason = isTimeout ? `\u8D85\u65F6(${DirectConfig.directTimeout}s)` : `\u5F02\u5E38: ${message}`;
|
|
2035
|
-
logger10.warn(`\u76F4\u8FDE${reason}\uFF0C${action}`);
|
|
2036
|
-
if (fallbackToProxy) {
|
|
2037
|
-
await safeContinue(route);
|
|
2038
|
-
} else {
|
|
2039
|
-
await safeAbort(route);
|
|
2040
|
-
}
|
|
2041
|
-
}
|
|
2042
|
-
};
|
|
2043
|
-
const blockRouteHandler = async (route) => {
|
|
2044
|
-
await safeAbort(route);
|
|
2045
|
-
};
|
|
2046
|
-
if (hasDirectRules) {
|
|
2047
|
-
for (const matcher of directRouteMatchers) {
|
|
2048
|
-
await page.route(matcher, directRouteHandler);
|
|
2049
|
-
}
|
|
2050
|
-
}
|
|
2051
|
-
if (hasBlockRules) {
|
|
2052
|
-
for (const matcher of blockRouteMatchers) {
|
|
2053
|
-
await page.route(matcher, blockRouteHandler);
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
};
|
|
2058
|
-
async function safeFulfill(route, options) {
|
|
2059
|
-
try {
|
|
2060
|
-
await route.fulfill(options);
|
|
2061
|
-
} catch (error) {
|
|
2062
|
-
if (!isIgnorableError(error)) {
|
|
2063
|
-
console.error(`[Interception] Fulfill Error: ${error.message}`);
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
async function safeContinue(route) {
|
|
2068
|
-
try {
|
|
2069
|
-
await route.continue();
|
|
2070
|
-
} catch (error) {
|
|
2071
|
-
if (!isIgnorableError(error)) {
|
|
2072
|
-
}
|
|
2073
|
-
}
|
|
2074
|
-
}
|
|
2075
|
-
async function safeAbort(route) {
|
|
2076
|
-
try {
|
|
2077
|
-
await route.abort();
|
|
2078
|
-
} catch (error) {
|
|
2079
|
-
if (!isIgnorableError(error)) {
|
|
2080
|
-
}
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
function isIgnorableError(error) {
|
|
2084
|
-
const msg = error.message;
|
|
2085
|
-
return msg.includes("already handled") || msg.includes("Target closed") || msg.includes("closed");
|
|
2086
|
-
}
|
|
2087
|
-
function createExtensionsRegex(extensions = []) {
|
|
2088
|
-
const normalized = Array.from(new Set(
|
|
2089
|
-
extensions.map((ext) => String(ext || "").toLowerCase().trim()).filter(Boolean).map((ext) => ext.startsWith(".") ? ext : `.${ext}`)
|
|
2090
|
-
));
|
|
2091
|
-
if (!normalized.length) return null;
|
|
2092
|
-
const escaped = normalized.map((ext) => escapeRegex(ext));
|
|
2093
|
-
return new RegExp(`(?:${escaped.join("|")})(?:\\?.*)?$`, "i");
|
|
2094
|
-
}
|
|
2095
|
-
function createDomainsRegex(domains = []) {
|
|
2096
|
-
const normalized = Array.from(new Set(
|
|
2097
|
-
domains.map((domain) => String(domain || "").toLowerCase().trim()).filter(Boolean)
|
|
2098
|
-
));
|
|
2099
|
-
if (!normalized.length) return null;
|
|
2100
|
-
const domainParts = normalized.map((domain) => `${escapeRegex(domain)}[^/:?#]*`);
|
|
2101
|
-
return new RegExp(`^https?:\\/\\/(?:${domainParts.join("|")})(?::\\d+)?(?:[/?#]|$)`, "i");
|
|
2102
|
-
}
|
|
2103
|
-
function escapeRegex(value) {
|
|
2104
|
-
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
1769
|
// src/mutation.js
|
|
2108
1770
|
var import_uuid2 = require("uuid");
|
|
2109
|
-
var
|
|
1771
|
+
var logger10 = createInternalLogger("Mutation");
|
|
2110
1772
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
2111
1773
|
Added: "added",
|
|
2112
1774
|
Changed: "changed",
|
|
@@ -2139,14 +1801,14 @@ var Mutation = {
|
|
|
2139
1801
|
const stableTime = options.stableTime ?? 5 * 1e3;
|
|
2140
1802
|
const timeout = options.timeout ?? 120 * 1e3;
|
|
2141
1803
|
const onMutation = options.onMutation;
|
|
2142
|
-
|
|
1804
|
+
logger10.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
|
|
2143
1805
|
if (initialTimeout > 0) {
|
|
2144
1806
|
const selectorQuery = selectorList.join(",");
|
|
2145
1807
|
try {
|
|
2146
1808
|
await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
|
|
2147
|
-
|
|
1809
|
+
logger10.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
|
|
2148
1810
|
} catch (e) {
|
|
2149
|
-
|
|
1811
|
+
logger10.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
|
|
2150
1812
|
throw e;
|
|
2151
1813
|
}
|
|
2152
1814
|
}
|
|
@@ -2162,7 +1824,7 @@ var Mutation = {
|
|
|
2162
1824
|
return "__CONTINUE__";
|
|
2163
1825
|
}
|
|
2164
1826
|
});
|
|
2165
|
-
|
|
1827
|
+
logger10.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
|
|
2166
1828
|
} catch (e) {
|
|
2167
1829
|
}
|
|
2168
1830
|
}
|
|
@@ -2277,9 +1939,9 @@ var Mutation = {
|
|
|
2277
1939
|
{ selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
|
|
2278
1940
|
);
|
|
2279
1941
|
if (result.mutationCount === 0 && result.stableTime === 0) {
|
|
2280
|
-
|
|
1942
|
+
logger10.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
|
|
2281
1943
|
}
|
|
2282
|
-
|
|
1944
|
+
logger10.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
|
|
2283
1945
|
return result;
|
|
2284
1946
|
},
|
|
2285
1947
|
/**
|
|
@@ -2299,7 +1961,7 @@ var Mutation = {
|
|
|
2299
1961
|
const onMutation = options.onMutation;
|
|
2300
1962
|
const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
|
|
2301
1963
|
const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
|
|
2302
|
-
|
|
1964
|
+
logger10.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
|
|
2303
1965
|
const monitorKey = generateKey("pk_mon");
|
|
2304
1966
|
const callbackName = generateKey("pk_mon_cb");
|
|
2305
1967
|
const cleanerName = generateKey("pk_mon_clean");
|
|
@@ -2442,7 +2104,7 @@ var Mutation = {
|
|
|
2442
2104
|
return total;
|
|
2443
2105
|
};
|
|
2444
2106
|
}, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
|
|
2445
|
-
|
|
2107
|
+
logger10.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
|
|
2446
2108
|
return {
|
|
2447
2109
|
stop: async () => {
|
|
2448
2110
|
let totalMutations = 0;
|
|
@@ -2455,7 +2117,7 @@ var Mutation = {
|
|
|
2455
2117
|
}, cleanerName);
|
|
2456
2118
|
} catch (e) {
|
|
2457
2119
|
}
|
|
2458
|
-
|
|
2120
|
+
logger10.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
|
|
2459
2121
|
return { totalMutations };
|
|
2460
2122
|
}
|
|
2461
2123
|
};
|
|
@@ -3276,7 +2938,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
3276
2938
|
};
|
|
3277
2939
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
3278
2940
|
var Logger = {
|
|
3279
|
-
setLogger: (
|
|
2941
|
+
setLogger: (logger12) => setDefaultLogger(logger12),
|
|
3280
2942
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
3281
2943
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
3282
2944
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -3284,15 +2946,15 @@ var Logger = {
|
|
|
3284
2946
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
3285
2947
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
3286
2948
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
3287
|
-
useTemplate: (
|
|
3288
|
-
if (
|
|
2949
|
+
useTemplate: (logger12) => {
|
|
2950
|
+
if (logger12) return createTemplateLogger(createBaseLogger("", logger12));
|
|
3289
2951
|
return createTemplateLogger();
|
|
3290
2952
|
}
|
|
3291
2953
|
};
|
|
3292
2954
|
|
|
3293
2955
|
// src/share.js
|
|
3294
2956
|
var import_delay3 = __toESM(require("delay"), 1);
|
|
3295
|
-
var
|
|
2957
|
+
var logger11 = createInternalLogger("Share");
|
|
3296
2958
|
var DEFAULT_TIMEOUT_MS = 50 * 1e3;
|
|
3297
2959
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
3298
2960
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -3412,7 +3074,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
3412
3074
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
3413
3075
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
3414
3076
|
let matched = false;
|
|
3415
|
-
|
|
3077
|
+
logger11.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
3416
3078
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
3417
3079
|
mode,
|
|
3418
3080
|
onMutation: (context = {}) => {
|
|
@@ -3430,12 +3092,12 @@ ${text}`;
|
|
|
3430
3092
|
});
|
|
3431
3093
|
}
|
|
3432
3094
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
3433
|
-
|
|
3095
|
+
logger11.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
3434
3096
|
}
|
|
3435
3097
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
3436
3098
|
if (!candidate) return;
|
|
3437
3099
|
matched = true;
|
|
3438
|
-
|
|
3100
|
+
logger11.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
3439
3101
|
if (onMatch) {
|
|
3440
3102
|
onMatch({
|
|
3441
3103
|
link: candidate,
|
|
@@ -3451,7 +3113,7 @@ ${text}`;
|
|
|
3451
3113
|
return {
|
|
3452
3114
|
stop: async () => {
|
|
3453
3115
|
const result = await monitor.stop();
|
|
3454
|
-
|
|
3116
|
+
logger11.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
3455
3117
|
return result;
|
|
3456
3118
|
}
|
|
3457
3119
|
};
|
|
@@ -3491,8 +3153,8 @@ var Share = {
|
|
|
3491
3153
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
3492
3154
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
3493
3155
|
}
|
|
3494
|
-
|
|
3495
|
-
|
|
3156
|
+
logger11.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
3157
|
+
logger11.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
3496
3158
|
const stats = {
|
|
3497
3159
|
actionTimedOut: false,
|
|
3498
3160
|
domMutationCount: 0,
|
|
@@ -3517,7 +3179,7 @@ var Share = {
|
|
|
3517
3179
|
link: validated,
|
|
3518
3180
|
payloadText: String(payloadText || "")
|
|
3519
3181
|
};
|
|
3520
|
-
|
|
3182
|
+
logger11.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
3521
3183
|
return true;
|
|
3522
3184
|
};
|
|
3523
3185
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -3552,7 +3214,7 @@ var Share = {
|
|
|
3552
3214
|
try {
|
|
3553
3215
|
await monitor.stop();
|
|
3554
3216
|
} catch (error) {
|
|
3555
|
-
|
|
3217
|
+
logger11.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
3556
3218
|
}
|
|
3557
3219
|
};
|
|
3558
3220
|
const onResponse = async (response) => {
|
|
@@ -3565,29 +3227,29 @@ var Share = {
|
|
|
3565
3227
|
stats.responseSampleUrls.push(url);
|
|
3566
3228
|
}
|
|
3567
3229
|
if (stats.responseObserved <= 5) {
|
|
3568
|
-
|
|
3230
|
+
logger11.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
3569
3231
|
}
|
|
3570
3232
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
3571
3233
|
stats.responseMatched += 1;
|
|
3572
3234
|
stats.lastMatchedUrl = url;
|
|
3573
|
-
|
|
3235
|
+
logger11.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
3574
3236
|
const text = await response.text();
|
|
3575
3237
|
const hit = resolveResponseCandidate(text);
|
|
3576
3238
|
if (!hit?.link) {
|
|
3577
3239
|
if (stats.responseMatched <= 3) {
|
|
3578
|
-
|
|
3240
|
+
logger11.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
3579
3241
|
}
|
|
3580
3242
|
return;
|
|
3581
3243
|
}
|
|
3582
3244
|
stats.responseResolved += 1;
|
|
3583
|
-
|
|
3245
|
+
logger11.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
3584
3246
|
setCandidate("response", hit.link, hit.payloadText);
|
|
3585
3247
|
} catch (error) {
|
|
3586
|
-
|
|
3248
|
+
logger11.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
3587
3249
|
}
|
|
3588
3250
|
};
|
|
3589
3251
|
if (share.mode === "dom") {
|
|
3590
|
-
|
|
3252
|
+
logger11.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
3591
3253
|
domMonitor = await createDomShareMonitor(page, {
|
|
3592
3254
|
prefix: share.prefix,
|
|
3593
3255
|
selectors: domSelectors,
|
|
@@ -3602,14 +3264,14 @@ var Share = {
|
|
|
3602
3264
|
});
|
|
3603
3265
|
}
|
|
3604
3266
|
if (share.mode === "response") {
|
|
3605
|
-
|
|
3267
|
+
logger11.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
3606
3268
|
page.on("response", onResponse);
|
|
3607
3269
|
}
|
|
3608
3270
|
const deadline = Date.now() + timeoutMs;
|
|
3609
3271
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
3610
3272
|
try {
|
|
3611
3273
|
const actionTimeout = getRemainingMs();
|
|
3612
|
-
|
|
3274
|
+
logger11.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
3613
3275
|
if (actionTimeout > 0) {
|
|
3614
3276
|
let timer = null;
|
|
3615
3277
|
let actionError = null;
|
|
@@ -3623,21 +3285,21 @@ var Share = {
|
|
|
3623
3285
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
3624
3286
|
if (timer) clearTimeout(timer);
|
|
3625
3287
|
if (actionResult === "__ACTION_ERROR__") {
|
|
3626
|
-
|
|
3288
|
+
logger11.fail("captureLink.performActions", actionError);
|
|
3627
3289
|
throw actionError;
|
|
3628
3290
|
}
|
|
3629
3291
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
3630
3292
|
stats.actionTimedOut = true;
|
|
3631
|
-
|
|
3293
|
+
logger11.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
3632
3294
|
} else {
|
|
3633
|
-
|
|
3295
|
+
logger11.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
3634
3296
|
}
|
|
3635
3297
|
}
|
|
3636
3298
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
3637
3299
|
while (true) {
|
|
3638
3300
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
3639
3301
|
if (selected?.link) {
|
|
3640
|
-
|
|
3302
|
+
logger11.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
3641
3303
|
return {
|
|
3642
3304
|
link: selected.link,
|
|
3643
3305
|
payloadText: selected.payloadText,
|
|
@@ -3649,7 +3311,7 @@ var Share = {
|
|
|
3649
3311
|
if (remaining <= 0) break;
|
|
3650
3312
|
const now = Date.now();
|
|
3651
3313
|
if (now >= nextProgressLogTs) {
|
|
3652
|
-
|
|
3314
|
+
logger11.info(
|
|
3653
3315
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
3654
3316
|
);
|
|
3655
3317
|
nextProgressLogTs = now + 5e3;
|
|
@@ -3657,11 +3319,11 @@ var Share = {
|
|
|
3657
3319
|
await (0, import_delay3.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
3658
3320
|
}
|
|
3659
3321
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
3660
|
-
|
|
3322
|
+
logger11.warning(
|
|
3661
3323
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
3662
3324
|
);
|
|
3663
3325
|
}
|
|
3664
|
-
|
|
3326
|
+
logger11.warning(
|
|
3665
3327
|
`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"}`
|
|
3666
3328
|
);
|
|
3667
3329
|
return {
|
|
@@ -3673,7 +3335,7 @@ var Share = {
|
|
|
3673
3335
|
} finally {
|
|
3674
3336
|
if (share.mode === "response") {
|
|
3675
3337
|
page.off("response", onResponse);
|
|
3676
|
-
|
|
3338
|
+
logger11.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
3677
3339
|
}
|
|
3678
3340
|
await stopDomMonitor();
|
|
3679
3341
|
}
|
|
@@ -3761,7 +3423,6 @@ var usePlaywrightToolKit = () => {
|
|
|
3761
3423
|
Captcha,
|
|
3762
3424
|
Sse,
|
|
3763
3425
|
Errors: errors_exports,
|
|
3764
|
-
Interception,
|
|
3765
3426
|
Mutation,
|
|
3766
3427
|
Display,
|
|
3767
3428
|
Logger,
|