@skrillex1224/playwright-toolkit 2.0.92 → 2.0.94

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/index.js CHANGED
@@ -1171,8 +1171,8 @@ var Sse = {
1171
1171
  }
1172
1172
  };
1173
1173
 
1174
- // src/blocking.js
1175
- var logger9 = createLogger("Blocking");
1174
+ // src/interception.js
1175
+ var logger9 = createLogger("Interception");
1176
1176
  var ARCHIVE_EXTENSIONS = [".7z", ".zip", ".rar", ".gz", ".bz2", ".tar", ".zst"];
1177
1177
  var EXECUTABLE_EXTENSIONS = [".exe", ".apk", ".bin", ".dmg", ".jar", ".class"];
1178
1178
  var DOCUMENT_EXTENSIONS = [".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".csv"];
@@ -1219,20 +1219,11 @@ var DEFAULT_BLOCKING_CONFIG = {
1219
1219
  /** 额外自定义扩展名列表 */
1220
1220
  customExtensions: []
1221
1221
  };
1222
- var Blocking = {
1222
+ var Interception = {
1223
1223
  /**
1224
1224
  * 根据配置生成需要屏蔽的扩展名列表
1225
1225
  *
1226
- * @param {Object} [config] - 屏蔽配置,缺省则使用默认配置
1227
- * @param {boolean} [config.blockArchive] - 是否屏蔽压缩包
1228
- * @param {boolean} [config.blockExecutable] - 是否屏蔽可执行文件
1229
- * @param {boolean} [config.blockDocument] - 是否屏蔽办公文档
1230
- * @param {boolean} [config.blockImage] - 是否屏蔽图片
1231
- * @param {boolean} [config.blockMedia] - 是否屏蔽音视频
1232
- * @param {boolean} [config.blockFont] - 是否屏蔽字体
1233
- * @param {boolean} [config.blockCss] - 是否屏蔽 CSS
1234
- * @param {boolean} [config.blockOther] - 是否屏蔽其他资源
1235
- * @param {string[]} [config.customExtensions] - 额外自定义扩展名
1226
+ * @param {Object} [config] - 屏蔽配置
1236
1227
  * @returns {string[]} 需要屏蔽的扩展名列表
1237
1228
  */
1238
1229
  getBlockedExtensions(config = {}) {
@@ -1251,45 +1242,6 @@ var Blocking = {
1251
1242
  }
1252
1243
  return [...new Set(extensions)];
1253
1244
  },
1254
- /**
1255
- * 设置资源屏蔽规则
1256
- * 拦截指定扩展名的请求,优化加载速度并绕过代理问题
1257
- *
1258
- * @param {import('playwright').Page} page - Playwright Page 对象
1259
- * @param {Object} [config] - 屏蔽配置
1260
- * @returns {Promise<void>}
1261
- */
1262
- async setupBlockingResources(page, config = {}) {
1263
- const mergedConfig = { ...DEFAULT_BLOCKING_CONFIG, ...config };
1264
- const blockedExtensions = this.getBlockedExtensions(mergedConfig);
1265
- const enabledCategories = [];
1266
- if (mergedConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
1267
- if (mergedConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
1268
- if (mergedConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
1269
- if (mergedConfig.blockImage) enabledCategories.push("\u56FE\u7247");
1270
- if (mergedConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
1271
- if (mergedConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
1272
- if (mergedConfig.blockCss) enabledCategories.push("CSS");
1273
- if (mergedConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
1274
- if (mergedConfig.customExtensions?.length > 0) {
1275
- enabledCategories.push(`\u81EA\u5B9A\u4E49(${mergedConfig.customExtensions.join(",")})`);
1276
- }
1277
- logger9.start("setupBlockingResources", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
1278
- await page.route("**/*", async (route) => {
1279
- const url = route.request().url();
1280
- const urlLower = url.toLowerCase();
1281
- const shouldBlock = blockedExtensions.some((ext) => {
1282
- const urlPath = urlLower.split("?")[0];
1283
- return urlPath.endsWith(ext);
1284
- });
1285
- if (shouldBlock) {
1286
- logger9.debug(`blocked: ${url.substring(0, 120)}`);
1287
- return route.abort();
1288
- }
1289
- return route.continue();
1290
- });
1291
- logger9.success("setupBlockingResources", `\u5171 ${blockedExtensions.length} \u79CD\u6269\u5C55\u540D`);
1292
- },
1293
1245
  /**
1294
1246
  * 获取所有可用的扩展名分类信息
1295
1247
  *
@@ -1308,82 +1260,92 @@ var Blocking = {
1308
1260
  };
1309
1261
  },
1310
1262
  /**
1311
- * 设置 CDN 直连规则
1312
- * 对于指定域名的请求,使用 Node.js 原生 fetch 直连获取(绕过浏览器代理)
1263
+ * 设置网络拦截规则(资源屏蔽 + CDN 直连)
1264
+ *
1265
+ * 工作流程:
1266
+ * 1. 检查请求是否在屏蔽列表中 → 如果是,直接 abort
1267
+ * 2. 检查是否匹配直连域名 → 如果是,使用 Node.js fetch 直连
1268
+ * 3. 其他请求正常走代理
1313
1269
  *
1314
1270
  * 适用场景:
1315
- * - 代理 IP 无法访问某些 CDN 域名(如 statics.moonshot.cn)
1271
+ * - 代理 IP 无法访问某些 CDN 域名
1316
1272
  * - 需要加速静态资源加载
1317
- *
1318
- * 注意事项:
1319
- * - 仅当代码运行在国内环境(本地/国内服务器)时,直连才能访问国内 CDN
1320
- * - 如果在海外服务器(如 Apify 云端)运行,直连仍使用海外 IP,可能依然无法访问
1273
+ * - 屏蔽不必要的资源请求
1321
1274
  *
1322
1275
  * @param {import('playwright').Page} page - Playwright Page 对象
1323
1276
  * @param {Object} [options] - 配置选项
1324
- * @param {string[]} [options.domains] - 需要直连的域名列表
1325
- * @param {string[]} [options.extensions] - 需要直连的扩展名列表(可选,默认 CSS/JS/字体)
1277
+ * @param {string[]} [options.directDomains] - 需要直连的域名列表
1278
+ * @param {Object} [options.blockingConfig] - 资源屏蔽配置
1326
1279
  * @param {boolean} [options.fallbackToProxy] - 直连失败时是否回退到代理(默认 true)
1327
1280
  * @returns {Promise<void>}
1328
1281
  */
1329
- async setupDirectConnect(page, options = {}) {
1282
+ async setup(page, options = {}) {
1330
1283
  const {
1331
- domains = [],
1332
- extensions = [".css", ".js", ".woff", ".woff2", ".ttf", ".otf"],
1284
+ directDomains = [],
1285
+ blockingConfig = {},
1333
1286
  fallbackToProxy = true
1334
1287
  } = options;
1335
- if (domains.length === 0) {
1336
- logger9.warn("setupDirectConnect", "\u672A\u6307\u5B9A\u57DF\u540D\u5217\u8868\uFF0C\u8DF3\u8FC7\u76F4\u8FDE\u914D\u7F6E");
1337
- return;
1338
- }
1339
- logger9.start("setupDirectConnect", `\u57DF\u540D: [${domains.join(", ")}]`);
1340
- let directCount = 0;
1341
- let fallbackCount = 0;
1288
+ const mergedBlockingConfig = { ...DEFAULT_BLOCKING_CONFIG, ...blockingConfig };
1289
+ const blockedExtensions = this.getBlockedExtensions(mergedBlockingConfig);
1290
+ const enabledCategories = [];
1291
+ if (mergedBlockingConfig.blockArchive) enabledCategories.push("\u538B\u7F29\u5305");
1292
+ if (mergedBlockingConfig.blockExecutable) enabledCategories.push("\u53EF\u6267\u884C\u6587\u4EF6");
1293
+ if (mergedBlockingConfig.blockDocument) enabledCategories.push("\u529E\u516C\u6587\u6863");
1294
+ if (mergedBlockingConfig.blockImage) enabledCategories.push("\u56FE\u7247");
1295
+ if (mergedBlockingConfig.blockMedia) enabledCategories.push("\u97F3\u89C6\u9891");
1296
+ if (mergedBlockingConfig.blockFont) enabledCategories.push("\u5B57\u4F53");
1297
+ if (mergedBlockingConfig.blockCss) enabledCategories.push("CSS");
1298
+ if (mergedBlockingConfig.blockOther) enabledCategories.push("\u5176\u4ED6");
1299
+ const hasDirectDomains = directDomains.length > 0;
1300
+ logger9.start("setup", hasDirectDomains ? `\u76F4\u8FDE\u57DF\u540D: [${directDomains.join(", ")}]` : "\u4EC5\u8D44\u6E90\u5C4F\u853D\u6A21\u5F0F");
1342
1301
  await page.route("**/*", async (route) => {
1343
1302
  const request = route.request();
1344
1303
  const url = request.url();
1345
1304
  const urlLower = url.toLowerCase();
1346
1305
  const urlPath = urlLower.split("?")[0];
1347
- const matchesDomain = domains.some((domain) => url.includes(domain));
1348
- const matchesExtension = extensions.length === 0 || extensions.some((ext) => urlPath.endsWith(ext));
1349
- if (matchesDomain && matchesExtension) {
1350
- try {
1351
- const response = await fetch(url, {
1352
- method: request.method(),
1353
- headers: request.headers()
1354
- // 不传 agent 参数 = 直连(使用服务器本地网络)
1355
- });
1356
- if (!response.ok) {
1357
- throw new Error(`HTTP ${response.status}`);
1358
- }
1359
- const buffer = await response.arrayBuffer();
1360
- const body = Buffer.from(buffer);
1361
- const headers = {};
1362
- response.headers.forEach((value, key) => {
1363
- headers[key] = value;
1364
- });
1365
- directCount++;
1366
- logger9.debug(`direct: ${url.substring(0, 100)}`);
1367
- await route.fulfill({
1368
- status: response.status,
1369
- headers,
1370
- body
1371
- });
1372
- return;
1373
- } catch (e) {
1374
- if (fallbackToProxy) {
1375
- fallbackCount++;
1376
- logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
1377
- return route.continue();
1378
- } else {
1379
- logger9.warn("setupDirectConnect", `\u76F4\u8FDE\u5931\u8D25\u4E14\u4E0D\u56DE\u9000: ${url.substring(0, 80)}`);
1380
- return route.abort();
1306
+ const shouldBlock = blockedExtensions.some((ext) => urlPath.endsWith(ext));
1307
+ if (shouldBlock) {
1308
+ logger9.debug(`blocked: ${url.substring(0, 100)}`);
1309
+ return route.abort();
1310
+ }
1311
+ if (hasDirectDomains) {
1312
+ const matchesDomain = directDomains.some((domain) => url.includes(domain));
1313
+ if (matchesDomain) {
1314
+ try {
1315
+ const response = await fetch(url, {
1316
+ method: request.method(),
1317
+ headers: request.headers()
1318
+ });
1319
+ if (!response.ok) {
1320
+ throw new Error(`HTTP ${response.status}`);
1321
+ }
1322
+ const buffer = await response.arrayBuffer();
1323
+ const body = Buffer.from(buffer);
1324
+ const headers = {};
1325
+ response.headers.forEach((value, key) => {
1326
+ headers[key] = value;
1327
+ });
1328
+ logger9.debug(`direct: ${url.substring(0, 100)}`);
1329
+ await route.fulfill({
1330
+ status: response.status,
1331
+ headers,
1332
+ body
1333
+ });
1334
+ return;
1335
+ } catch (e) {
1336
+ if (fallbackToProxy) {
1337
+ logger9.debug(`fallback: ${url.substring(0, 80)} (${e.message})`);
1338
+ return route.continue();
1339
+ } else {
1340
+ logger9.warn("setup", `\u76F4\u8FDE\u5931\u8D25: ${url.substring(0, 80)}`);
1341
+ return route.abort();
1342
+ }
1381
1343
  }
1382
1344
  }
1383
1345
  }
1384
1346
  return route.continue();
1385
1347
  });
1386
- logger9.success("setupDirectConnect", `\u6269\u5C55\u540D: [${extensions.join(", ")}]`);
1348
+ logger9.success("setup", `\u5C4F\u853D\u5206\u7C7B: [${enabledCategories.join(", ")}]`);
1387
1349
  }
1388
1350
  };
1389
1351
 
@@ -1400,7 +1362,7 @@ var usePlaywrightToolKit = () => {
1400
1362
  Captcha,
1401
1363
  Sse,
1402
1364
  Errors: errors_exports,
1403
- Blocking
1365
+ Interception
1404
1366
  };
1405
1367
  };
1406
1368
  export {