@skrillex1224/playwright-toolkit 2.1.159 → 2.1.161

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.cjs CHANGED
@@ -335,18 +335,18 @@ var fallbackLog = {
335
335
  error: (...args) => console.error(...args),
336
336
  debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
337
337
  };
338
- var resolveLogMethod = (logger12, name) => {
339
- if (logger12 && typeof logger12[name] === "function") {
340
- return logger12[name].bind(logger12);
338
+ var resolveLogMethod = (logger13, name) => {
339
+ if (logger13 && typeof logger13[name] === "function") {
340
+ return logger13[name].bind(logger13);
341
341
  }
342
- if (name === "warning" && logger12 && typeof logger12.warn === "function") {
343
- return logger12.warn.bind(logger12);
342
+ if (name === "warning" && logger13 && typeof logger13.warn === "function") {
343
+ return logger13.warn.bind(logger13);
344
344
  }
345
345
  return fallbackLog[name];
346
346
  };
347
347
  var defaultLogger = null;
348
- var setDefaultLogger = (logger12) => {
349
- defaultLogger = logger12;
348
+ var setDefaultLogger = (logger13) => {
349
+ defaultLogger = logger13;
350
350
  };
351
351
  var resolveLogger = (explicitLogger) => {
352
352
  if (explicitLogger && typeof explicitLogger.info === "function") {
@@ -373,8 +373,8 @@ var colorize = (text, color) => {
373
373
  var createBaseLogger = (prefix = "", explicitLogger) => {
374
374
  const name = prefix ? String(prefix) : "";
375
375
  const dispatch = (methodName, icon, message, color) => {
376
- const logger12 = resolveLogger(explicitLogger);
377
- const logFn = resolveLogMethod(logger12, methodName);
376
+ const logger13 = resolveLogger(explicitLogger);
377
+ const logFn = resolveLogMethod(logger13, methodName);
378
378
  const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
379
379
  const line = formatLine(name, icon, message);
380
380
  const coloredLine = colorize(line, color);
@@ -420,6 +420,99 @@ function createInternalLogger(moduleName, explicitLogger) {
420
420
  };
421
421
  }
422
422
 
423
+ // src/internals/screenshot.js
424
+ var logger = createInternalLogger("Screenshot");
425
+ var DEFAULT_TIMEOUT_MS = 5e3;
426
+ var FORCED_FULLPAGE_TYPE = "jpeg";
427
+ var FORCED_FULLPAGE_QUALITY = 50;
428
+ var SUPPORTED_TYPES = /* @__PURE__ */ new Set(["png", "jpeg", "webp"]);
429
+ var toPositiveNumber = (value, fallback = 0) => {
430
+ const n = Number(value);
431
+ if (!Number.isFinite(n) || n <= 0) return fallback;
432
+ return n;
433
+ };
434
+ var normalizeType = (value) => {
435
+ const raw = String(value || "png").trim().toLowerCase();
436
+ if (!SUPPORTED_TYPES.has(raw)) return "png";
437
+ return raw;
438
+ };
439
+ var normalizeQuality = (value, type) => {
440
+ if (type !== "jpeg" && type !== "webp") return void 0;
441
+ const n = Number(value);
442
+ if (!Number.isFinite(n)) return void 0;
443
+ const rounded = Math.round(n);
444
+ if (rounded < 0 || rounded > 100) return void 0;
445
+ return rounded;
446
+ };
447
+ var buildFullPageClip = (metrics, viewport, maxClipHeight) => {
448
+ const contentSize = metrics && typeof metrics === "object" ? metrics.contentSize || null : null;
449
+ const width = Math.max(1, Math.ceil(contentSize?.width || viewport.width || 1));
450
+ let height = Math.max(1, Math.ceil(contentSize?.height || viewport.height || 1));
451
+ if (maxClipHeight > 0) {
452
+ height = Math.min(height, maxClipHeight);
453
+ }
454
+ return {
455
+ x: 0,
456
+ y: 0,
457
+ width,
458
+ height,
459
+ scale: 1
460
+ };
461
+ };
462
+ var capturePageScreenshot = async (page, options = {}) => {
463
+ const fullPage = Boolean(options.fullPage);
464
+ const type = fullPage ? FORCED_FULLPAGE_TYPE : normalizeType(options.type);
465
+ const quality = fullPage ? FORCED_FULLPAGE_QUALITY : normalizeQuality(options.quality, type);
466
+ const timeout = toPositiveNumber(options.timeout, DEFAULT_TIMEOUT_MS);
467
+ const maxClipHeight = Math.round(toPositiveNumber(options.maxClipHeight, 0));
468
+ const fallbackOptions = {
469
+ type: type === "webp" ? "png" : type,
470
+ fullPage
471
+ };
472
+ if (quality !== void 0 && fallbackOptions.type === "jpeg") {
473
+ fallbackOptions.quality = quality;
474
+ }
475
+ if (timeout > 0) {
476
+ fallbackOptions.timeout = timeout;
477
+ }
478
+ try {
479
+ const context = page && typeof page.context === "function" ? page.context() : null;
480
+ if (!context || typeof context.newCDPSession !== "function") {
481
+ throw new Error("CDP session is not available");
482
+ }
483
+ const session = await context.newCDPSession(page);
484
+ try {
485
+ const metrics = await session.send("Page.getLayoutMetrics");
486
+ const viewport = page.viewportSize() || { width: 1280, height: 720 };
487
+ const captureParams = {
488
+ format: type,
489
+ fromSurface: true,
490
+ captureBeyondViewport: fullPage,
491
+ optimizeForSpeed: true
492
+ };
493
+ if (quality !== void 0) {
494
+ captureParams.quality = quality;
495
+ }
496
+ if (fullPage) {
497
+ captureParams.clip = buildFullPageClip(metrics, viewport, maxClipHeight);
498
+ }
499
+ const result = await session.send("Page.captureScreenshot", captureParams);
500
+ if (!result || typeof result.data !== "string" || !result.data) {
501
+ throw new Error("CDP returned empty screenshot data");
502
+ }
503
+ return Buffer.from(result.data, "base64");
504
+ } finally {
505
+ if (typeof session.detach === "function") {
506
+ await session.detach().catch(() => {
507
+ });
508
+ }
509
+ }
510
+ } catch (error) {
511
+ logger.warning(`CDP \u622A\u56FE\u5931\u8D25\uFF0C\u56DE\u9000 page.screenshot: ${error?.message || error}`);
512
+ return await page.screenshot(fallbackOptions);
513
+ }
514
+ };
515
+
423
516
  // src/errors.js
424
517
  var errors_exports = {};
425
518
  __export(errors_exports, {
@@ -493,7 +586,7 @@ var getTrafficSnapshot = () => {
493
586
  };
494
587
 
495
588
  // src/apify-kit.js
496
- var logger = createInternalLogger("ApifyKit");
589
+ var logger2 = createInternalLogger("ApifyKit");
497
590
  async function createApifyKit() {
498
591
  let apify = null;
499
592
  try {
@@ -521,29 +614,29 @@ async function createApifyKit() {
521
614
  const { times: retryTimes = 0, mode: retryMode = "direct", before: beforeRetry } = retry;
522
615
  const executeAction = async (attemptNumber) => {
523
616
  const attemptLabel = attemptNumber > 0 ? ` (\u91CD\u8BD5 #${attemptNumber})` : "";
524
- logger.start(`[Step] ${step}${attemptLabel}`);
617
+ logger2.start(`[Step] ${step}${attemptLabel}`);
525
618
  try {
526
619
  const result = await actionFn();
527
- logger.success(`[Step] ${step}${attemptLabel}`);
620
+ logger2.success(`[Step] ${step}${attemptLabel}`);
528
621
  return { success: true, result };
529
622
  } catch (error) {
530
- logger.fail(`[Step] ${step}${attemptLabel}`, error);
623
+ logger2.fail(`[Step] ${step}${attemptLabel}`, error);
531
624
  return { success: false, error };
532
625
  }
533
626
  };
534
627
  const prepareForRetry = async (attemptNumber) => {
535
628
  if (typeof beforeRetry === "function") {
536
- logger.start(`[RetryStep] \u6267\u884C\u81EA\u5B9A\u4E49 before \u94A9\u5B50 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
629
+ logger2.start(`[RetryStep] \u6267\u884C\u81EA\u5B9A\u4E49 before \u94A9\u5B50 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
537
630
  await beforeRetry(page, attemptNumber);
538
- logger.success(`[RetryStep] before \u94A9\u5B50\u5B8C\u6210`);
631
+ logger2.success(`[RetryStep] before \u94A9\u5B50\u5B8C\u6210`);
539
632
  } else if (retryMode === "refresh") {
540
- logger.start(`[RetryStep] \u5237\u65B0\u9875\u9762 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
633
+ logger2.start(`[RetryStep] \u5237\u65B0\u9875\u9762 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
541
634
  await page.reload({ waitUntil: "domcontentloaded" });
542
- logger.success(`[RetryStep] \u9875\u9762\u5237\u65B0\u5B8C\u6210`);
635
+ logger2.success(`[RetryStep] \u9875\u9762\u5237\u65B0\u5B8C\u6210`);
543
636
  } else {
544
- logger.start(`[RetryStep] \u7B49\u5F85 3 \u79D2 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
637
+ logger2.start(`[RetryStep] \u7B49\u5F85 3 \u79D2 (\u7B2C ${attemptNumber} \u6B21\u91CD\u8BD5)`);
545
638
  await new Promise((resolve) => setTimeout(resolve, 3e3));
546
- logger.success(`[RetryStep] \u7B49\u5F85\u5B8C\u6210`);
639
+ logger2.success(`[RetryStep] \u7B49\u5F85\u5B8C\u6210`);
547
640
  }
548
641
  };
549
642
  let lastResult = await executeAction(0);
@@ -551,11 +644,11 @@ async function createApifyKit() {
551
644
  return lastResult.result;
552
645
  }
553
646
  for (let attempt = 1; attempt <= retryTimes; attempt++) {
554
- logger.start(`[RetryStep] \u51C6\u5907\u7B2C ${attempt}/${retryTimes} \u6B21\u91CD\u8BD5: ${step}`);
647
+ logger2.start(`[RetryStep] \u51C6\u5907\u7B2C ${attempt}/${retryTimes} \u6B21\u91CD\u8BD5: ${step}`);
555
648
  try {
556
649
  await prepareForRetry(attempt);
557
650
  } catch (prepareError) {
558
- logger.warn(`[RetryStep] \u91CD\u8BD5\u51C6\u5907\u5931\u8D25: ${prepareError.message}`);
651
+ logger2.warn(`[RetryStep] \u91CD\u8BD5\u51C6\u5907\u5931\u8D25: ${prepareError.message}`);
559
652
  continue;
560
653
  }
561
654
  lastResult = await executeAction(attempt);
@@ -568,11 +661,15 @@ async function createApifyKit() {
568
661
  let base64 = "\u622A\u56FE\u5931\u8D25";
569
662
  try {
570
663
  if (page) {
571
- const buffer = await page.screenshot({ fullPage: true, type: "jpeg", quality: 60 });
664
+ const buffer = await capturePageScreenshot(page, {
665
+ fullPage: true,
666
+ type: "jpeg",
667
+ quality: 60
668
+ });
572
669
  base64 = `data:image/jpeg;base64,${buffer.toString("base64")}`;
573
670
  }
574
671
  } catch (snapErr) {
575
- logger.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
672
+ logger2.warn(`\u622A\u56FE\u751F\u6210\u5931\u8D25: ${snapErr.message}`);
576
673
  }
577
674
  await this.pushFailed(finalError, {
578
675
  step,
@@ -615,7 +712,7 @@ async function createApifyKit() {
615
712
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
616
713
  data
617
714
  });
618
- logger.success("pushSuccess", "Data pushed");
715
+ logger2.success("pushSuccess", "Data pushed");
619
716
  },
620
717
  /**
621
718
  * 推送失败数据的通用方法(私有方法,仅供runStep内部使用)
@@ -639,7 +736,7 @@ async function createApifyKit() {
639
736
  context,
640
737
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
641
738
  });
642
- logger.success("pushFailed", "Error data pushed");
739
+ logger2.success("pushFailed", "Error data pushed");
643
740
  }
644
741
  };
645
742
  }
@@ -655,7 +752,7 @@ var ApifyKit = {
655
752
  };
656
753
 
657
754
  // src/internals/utils.js
658
- var logger2 = createInternalLogger("InternalUtils");
755
+ var logger3 = createInternalLogger("InternalUtils");
659
756
  var parseCookies = (cookieString, domain) => {
660
757
  const cookies = [];
661
758
  const pairs = cookieString.split(";").map((c) => c.trim());
@@ -673,7 +770,7 @@ var parseCookies = (cookieString, domain) => {
673
770
  cookies.push(cookie);
674
771
  }
675
772
  }
676
- logger2.success("parseCookies", `parsed ${cookies.length} cookies`);
773
+ logger3.success("parseCookies", `parsed ${cookies.length} cookies`);
677
774
  return cookies;
678
775
  };
679
776
 
@@ -716,7 +813,7 @@ var Utils = {
716
813
  };
717
814
 
718
815
  // src/anti-cheat.js
719
- var logger3 = createInternalLogger("AntiCheat");
816
+ var logger4 = createInternalLogger("AntiCheat");
720
817
  var BASE_CONFIG = Object.freeze({
721
818
  locale: "zh-CN",
722
819
  acceptLanguage: "zh-CN,zh;q=0.9",
@@ -778,7 +875,7 @@ var AntiCheat = {
778
875
  // src/humanize.js
779
876
  var import_delay = __toESM(require("delay"), 1);
780
877
  var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
781
- var logger4 = createInternalLogger("Humanize");
878
+ var logger5 = createInternalLogger("Humanize");
782
879
  var $CursorWeakMap = /* @__PURE__ */ new WeakMap();
783
880
  function $GetCursor(page) {
784
881
  const cursor = $CursorWeakMap.get(page);
@@ -806,13 +903,13 @@ var Humanize = {
806
903
  */
807
904
  async initializeCursor(page) {
808
905
  if ($CursorWeakMap.has(page)) {
809
- logger4.debug("initializeCursor: cursor already exists, skipping");
906
+ logger5.debug("initializeCursor: cursor already exists, skipping");
810
907
  return;
811
908
  }
812
- logger4.start("initializeCursor", "creating cursor");
909
+ logger5.start("initializeCursor", "creating cursor");
813
910
  const cursor = await (0, import_ghost_cursor_playwright.createCursor)(page);
814
911
  $CursorWeakMap.set(page, cursor);
815
- logger4.success("initializeCursor", "cursor initialized");
912
+ logger5.success("initializeCursor", "cursor initialized");
816
913
  },
817
914
  /**
818
915
  * 人类化鼠标移动 - 使用 ghost-cursor 移动到指定位置或元素
@@ -822,17 +919,17 @@ var Humanize = {
822
919
  */
823
920
  async humanMove(page, target) {
824
921
  const cursor = $GetCursor(page);
825
- logger4.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
922
+ logger5.start("humanMove", `target=${typeof target === "string" ? target : "element/coords"}`);
826
923
  try {
827
924
  if (typeof target === "string") {
828
925
  const element = await page.$(target);
829
926
  if (!element) {
830
- logger4.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
927
+ logger5.warn(`humanMove: \u5143\u7D20\u4E0D\u5B58\u5728 ${target}`);
831
928
  return false;
832
929
  }
833
930
  const box = await element.boundingBox();
834
931
  if (!box) {
835
- logger4.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
932
+ logger5.warn(`humanMove: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E ${target}`);
836
933
  return false;
837
934
  }
838
935
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.2;
@@ -848,10 +945,10 @@ var Humanize = {
848
945
  await cursor.actions.move({ x, y });
849
946
  }
850
947
  }
851
- logger4.success("humanMove");
948
+ logger5.success("humanMove");
852
949
  return true;
853
950
  } catch (error) {
854
- logger4.fail("humanMove", error);
951
+ logger5.fail("humanMove", error);
855
952
  throw error;
856
953
  }
857
954
  },
@@ -875,12 +972,12 @@ var Humanize = {
875
972
  maxDurationMs = maxSteps * 220 + 800
876
973
  } = options;
877
974
  const targetDesc = typeof target === "string" ? target : "ElementHandle";
878
- logger4.start("humanScroll", `target=${targetDesc}`);
975
+ logger5.start("humanScroll", `target=${targetDesc}`);
879
976
  let element;
880
977
  if (typeof target === "string") {
881
978
  element = await page.$(target);
882
979
  if (!element) {
883
- logger4.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
980
+ logger5.warn(`humanScroll | \u5143\u7D20\u672A\u627E\u5230: ${target}`);
884
981
  return { element: null, didScroll: false };
885
982
  }
886
983
  } else {
@@ -955,26 +1052,26 @@ var Humanize = {
955
1052
  try {
956
1053
  for (let i = 0; i < maxSteps; i++) {
957
1054
  if (Date.now() - startTime > maxDurationMs) {
958
- logger4.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
1055
+ logger5.warn(`humanScroll | \u8D85\u65F6\u4FDD\u62A4\u89E6\u53D1 (${maxDurationMs}ms)`);
959
1056
  return { element, didScroll };
960
1057
  }
961
1058
  const status = await checkVisibility();
962
1059
  if (status.code === "VISIBLE") {
963
1060
  if (status.isFixed) {
964
- logger4.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
1061
+ logger5.info("humanScroll | fixed \u5BB9\u5668\u5185\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
965
1062
  } else {
966
- logger4.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
1063
+ logger5.debug("humanScroll | \u5143\u7D20\u53EF\u89C1\u4E14\u65E0\u906E\u6321");
967
1064
  }
968
- logger4.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
1065
+ logger5.success("humanScroll", didScroll ? "\u5DF2\u6EDA\u52A8" : "\u65E0\u9700\u6EDA\u52A8");
969
1066
  return { element, didScroll };
970
1067
  }
971
- logger4.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
1068
+ logger5.debug(`humanScroll | \u6B65\u9AA4 ${i + 1}/${maxSteps}: ${status.reason} ${status.direction ? `(${status.direction})` : ""}`);
972
1069
  if (status.code === "OBSTRUCTED" && status.obstruction) {
973
- logger4.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
1070
+ logger5.debug(`humanScroll | \u88AB\u4EE5\u4E0B\u5143\u7D20\u906E\u6321 <${status.obstruction.tag} id="${status.obstruction.id}">`);
974
1071
  }
975
1072
  const scrollRect = await getScrollableRect();
976
1073
  if (!scrollRect && status.isFixed) {
977
- logger4.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
1074
+ logger5.warn("humanScroll | fixed \u5BB9\u5668\u5185\u4E14\u65E0\u53EF\u6EDA\u52A8\u7956\u5148\uFF0C\u8DF3\u8FC7\u6EDA\u52A8");
978
1075
  return { element, didScroll };
979
1076
  }
980
1077
  const stepMin = scrollRect ? Math.min(minStep, Math.max(60, scrollRect.height * 0.4)) : minStep;
@@ -1010,10 +1107,10 @@ var Humanize = {
1010
1107
  didScroll = true;
1011
1108
  await (0, import_delay.default)(this.jitterMs(20 + Math.random() * 40, 0.2));
1012
1109
  }
1013
- logger4.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
1110
+ logger5.warn(`humanScroll | \u5728 ${maxSteps} \u6B65\u540E\u65E0\u6CD5\u786E\u4FDD\u53EF\u89C1\u6027`);
1014
1111
  return { element, didScroll };
1015
1112
  } catch (error) {
1016
- logger4.fail("humanScroll", error);
1113
+ logger5.fail("humanScroll", error);
1017
1114
  throw error;
1018
1115
  }
1019
1116
  },
@@ -1031,7 +1128,7 @@ var Humanize = {
1031
1128
  const cursor = $GetCursor(page);
1032
1129
  const { reactionDelay = 250, throwOnMissing = true, scrollIfNeeded = true, restore = false } = options;
1033
1130
  const targetDesc = target == null ? "Current Position" : typeof target === "string" ? target : "ElementHandle";
1034
- logger4.start("humanClick", `target=${targetDesc}`);
1131
+ logger5.start("humanClick", `target=${targetDesc}`);
1035
1132
  const restoreOnce = async () => {
1036
1133
  if (restoreOnce.restored) return;
1037
1134
  restoreOnce.restored = true;
@@ -1040,14 +1137,14 @@ var Humanize = {
1040
1137
  await (0, import_delay.default)(this.jitterMs(1e3));
1041
1138
  await restoreOnce.do();
1042
1139
  } catch (restoreError) {
1043
- logger4.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
1140
+ logger5.warn(`humanClick: \u6062\u590D\u6EDA\u52A8\u4F4D\u7F6E\u5931\u8D25: ${restoreError.message}`);
1044
1141
  }
1045
1142
  };
1046
1143
  try {
1047
1144
  if (target == null) {
1048
1145
  await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
1049
1146
  await cursor.actions.click();
1050
- logger4.success("humanClick", "Clicked current position");
1147
+ logger5.success("humanClick", "Clicked current position");
1051
1148
  return true;
1052
1149
  }
1053
1150
  let element;
@@ -1057,7 +1154,7 @@ var Humanize = {
1057
1154
  if (throwOnMissing) {
1058
1155
  throw new Error(`\u627E\u4E0D\u5230\u5143\u7D20 ${target}`);
1059
1156
  }
1060
- logger4.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
1157
+ logger5.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${target}`);
1061
1158
  return false;
1062
1159
  }
1063
1160
  } else {
@@ -1073,7 +1170,7 @@ var Humanize = {
1073
1170
  if (throwOnMissing) {
1074
1171
  throw new Error("\u65E0\u6CD5\u83B7\u53D6\u5143\u7D20\u4F4D\u7F6E");
1075
1172
  }
1076
- logger4.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
1173
+ logger5.warn("humanClick: \u65E0\u6CD5\u83B7\u53D6\u4F4D\u7F6E\uFF0C\u8DF3\u8FC7\u70B9\u51FB");
1077
1174
  return false;
1078
1175
  }
1079
1176
  const x = box.x + box.width / 2 + (Math.random() - 0.5) * box.width * 0.3;
@@ -1082,11 +1179,11 @@ var Humanize = {
1082
1179
  await (0, import_delay.default)(this.jitterMs(reactionDelay, 0.4));
1083
1180
  await cursor.actions.click();
1084
1181
  await restoreOnce();
1085
- logger4.success("humanClick");
1182
+ logger5.success("humanClick");
1086
1183
  return true;
1087
1184
  } catch (error) {
1088
1185
  await restoreOnce();
1089
- logger4.fail("humanClick", error);
1186
+ logger5.fail("humanClick", error);
1090
1187
  throw error;
1091
1188
  }
1092
1189
  },
@@ -1097,9 +1194,9 @@ var Humanize = {
1097
1194
  */
1098
1195
  async randomSleep(baseMs, jitterPercent = 0.3) {
1099
1196
  const ms = this.jitterMs(baseMs, jitterPercent);
1100
- logger4.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
1197
+ logger5.start("randomSleep", `base=${baseMs}, actual=${ms}ms`);
1101
1198
  await (0, import_delay.default)(ms);
1102
- logger4.success("randomSleep");
1199
+ logger5.success("randomSleep");
1103
1200
  },
1104
1201
  /**
1105
1202
  * 模拟人类"注视"或"阅读"行为:鼠标在页面上随机微动
@@ -1109,7 +1206,7 @@ var Humanize = {
1109
1206
  async simulateGaze(page, baseDurationMs = 2500) {
1110
1207
  const cursor = $GetCursor(page);
1111
1208
  const durationMs = this.jitterMs(baseDurationMs, 0.4);
1112
- logger4.start("simulateGaze", `duration=${durationMs}ms`);
1209
+ logger5.start("simulateGaze", `duration=${durationMs}ms`);
1113
1210
  const startTime = Date.now();
1114
1211
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
1115
1212
  while (Date.now() - startTime < durationMs) {
@@ -1118,7 +1215,7 @@ var Humanize = {
1118
1215
  await cursor.actions.move({ x, y });
1119
1216
  await (0, import_delay.default)(this.jitterMs(600, 0.5));
1120
1217
  }
1121
- logger4.success("simulateGaze");
1218
+ logger5.success("simulateGaze");
1122
1219
  },
1123
1220
  /**
1124
1221
  * 人类化输入 - 带节奏变化(快-慢-停顿-偶尔加速)
@@ -1131,7 +1228,7 @@ var Humanize = {
1131
1228
  * @param {number} [options.pauseBase=800] - 停顿时长基础值 (ms),实际 ±50% 抖动
1132
1229
  */
1133
1230
  async humanType(page, selector, text, options = {}) {
1134
- logger4.start("humanType", `selector=${selector}, textLen=${text.length}`);
1231
+ logger5.start("humanType", `selector=${selector}, textLen=${text.length}`);
1135
1232
  const {
1136
1233
  baseDelay = 180,
1137
1234
  pauseProbability = 0.08,
@@ -1155,13 +1252,13 @@ var Humanize = {
1155
1252
  await (0, import_delay.default)(charDelay);
1156
1253
  if (Math.random() < pauseProbability && i < text.length - 1) {
1157
1254
  const pauseTime = this.jitterMs(pauseBase, 0.5);
1158
- logger4.debug(`\u505C\u987F ${pauseTime}ms...`);
1255
+ logger5.debug(`\u505C\u987F ${pauseTime}ms...`);
1159
1256
  await (0, import_delay.default)(pauseTime);
1160
1257
  }
1161
1258
  }
1162
- logger4.success("humanType");
1259
+ logger5.success("humanType");
1163
1260
  } catch (error) {
1164
- logger4.fail("humanType", error);
1261
+ logger5.fail("humanType", error);
1165
1262
  throw error;
1166
1263
  }
1167
1264
  },
@@ -1171,22 +1268,22 @@ var Humanize = {
1171
1268
  * @param {string} selector - 输入框选择器
1172
1269
  */
1173
1270
  async humanClear(page, selector) {
1174
- logger4.start("humanClear", `selector=${selector}`);
1271
+ logger5.start("humanClear", `selector=${selector}`);
1175
1272
  try {
1176
1273
  const locator = page.locator(selector);
1177
1274
  await locator.click();
1178
1275
  await (0, import_delay.default)(this.jitterMs(200, 0.4));
1179
1276
  const currentValue = await locator.inputValue();
1180
1277
  if (!currentValue || currentValue.length === 0) {
1181
- logger4.success("humanClear", "already empty");
1278
+ logger5.success("humanClear", "already empty");
1182
1279
  return;
1183
1280
  }
1184
1281
  await page.keyboard.press("Meta+A");
1185
1282
  await (0, import_delay.default)(this.jitterMs(100, 0.4));
1186
1283
  await page.keyboard.press("Backspace");
1187
- logger4.success("humanClear");
1284
+ logger5.success("humanClear");
1188
1285
  } catch (error) {
1189
- logger4.fail("humanClear", error);
1286
+ logger5.fail("humanClear", error);
1190
1287
  throw error;
1191
1288
  }
1192
1289
  },
@@ -1198,7 +1295,7 @@ var Humanize = {
1198
1295
  async warmUpBrowsing(page, baseDuration = 3500) {
1199
1296
  const cursor = $GetCursor(page);
1200
1297
  const durationMs = this.jitterMs(baseDuration, 0.4);
1201
- logger4.start("warmUpBrowsing", `duration=${durationMs}ms`);
1298
+ logger5.start("warmUpBrowsing", `duration=${durationMs}ms`);
1202
1299
  const startTime = Date.now();
1203
1300
  const viewportSize = page.viewportSize() || { width: 1920, height: 1080 };
1204
1301
  try {
@@ -1217,9 +1314,9 @@ var Humanize = {
1217
1314
  await (0, import_delay.default)(this.jitterMs(800, 0.5));
1218
1315
  }
1219
1316
  }
1220
- logger4.success("warmUpBrowsing");
1317
+ logger5.success("warmUpBrowsing");
1221
1318
  } catch (error) {
1222
- logger4.fail("warmUpBrowsing", error);
1319
+ logger5.fail("warmUpBrowsing", error);
1223
1320
  throw error;
1224
1321
  }
1225
1322
  },
@@ -1233,7 +1330,7 @@ var Humanize = {
1233
1330
  async naturalScroll(page, direction = "down", distance = 300, baseSteps = 5) {
1234
1331
  const steps = Math.max(3, baseSteps + Math.floor(Math.random() * 3) - 1);
1235
1332
  const actualDistance = this.jitterMs(distance, 0.15);
1236
- logger4.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
1333
+ logger5.start("naturalScroll", `dir=${direction}, dist=${actualDistance}, steps=${steps}`);
1237
1334
  const sign = direction === "down" ? 1 : -1;
1238
1335
  const stepDistance = actualDistance / steps;
1239
1336
  try {
@@ -1245,9 +1342,9 @@ var Humanize = {
1245
1342
  const baseDelay = 60 + i * 25;
1246
1343
  await (0, import_delay.default)(this.jitterMs(baseDelay, 0.3));
1247
1344
  }
1248
- logger4.success("naturalScroll");
1345
+ logger5.success("naturalScroll");
1249
1346
  } catch (error) {
1250
- logger4.fail("naturalScroll", error);
1347
+ logger5.fail("naturalScroll", error);
1251
1348
  throw error;
1252
1349
  }
1253
1350
  }
@@ -1315,7 +1412,7 @@ var resolveRouteByProxy = ({
1315
1412
  };
1316
1413
 
1317
1414
  // src/traffic-meter.js
1318
- var logger5 = createInternalLogger("TrafficMeter");
1415
+ var logger6 = createInternalLogger("TrafficMeter");
1319
1416
  var encoder = new TextEncoder();
1320
1417
  var toSafeNumber = (value) => {
1321
1418
  if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return 0;
@@ -1485,7 +1582,7 @@ var createTrafficMeter = ({
1485
1582
  session.on("Network.webSocketFrameSent", recordWebSocketFrameSent);
1486
1583
  session.on("Network.webSocketFrameReceived", recordWebSocketFrameReceived);
1487
1584
  } catch (error) {
1488
- logger5.warn(`CDP \u76D1\u542C\u6CE8\u518C\u5931\u8D25: ${error?.message || error}`);
1585
+ logger6.warn(`CDP \u76D1\u542C\u6CE8\u518C\u5931\u8D25: ${error?.message || error}`);
1489
1586
  }
1490
1587
  };
1491
1588
  const snapshot = () => {
@@ -1521,7 +1618,7 @@ var createTrafficMeter = ({
1521
1618
  };
1522
1619
 
1523
1620
  // src/launch.js
1524
- var logger6 = createInternalLogger("Launch");
1621
+ var logger7 = createInternalLogger("Launch");
1525
1622
  var resolveProxyLaunchOptions = (proxyConfiguration = {}) => {
1526
1623
  const config = proxyConfiguration && typeof proxyConfiguration === "object" && !Array.isArray(proxyConfiguration) ? proxyConfiguration : {};
1527
1624
  const proxyUrl = String(config.proxy_url || "").trim();
@@ -1573,15 +1670,15 @@ var Launch = {
1573
1670
  }
1574
1671
  const enableByPassLogger = Boolean(logOptions && logOptions.enable);
1575
1672
  if (enableByPassLogger && launchProxy) {
1576
- logger6.info(
1673
+ logger7.info(
1577
1674
  `[\u4EE3\u7406\u5DF2\u542F\u7528] \u4EE3\u7406\u670D\u52A1=${launchProxy.server} \u76F4\u8FDE\u57DF\u540D=${(byPassDomains || []).join(",")}`
1578
1675
  );
1579
1676
  } else if (enableByPassLogger && enableProxy && !launchProxy) {
1580
- logger6.info(
1677
+ logger7.info(
1581
1678
  `[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=true \u4F46 proxy_url \u4E3A\u7A7A`
1582
1679
  );
1583
1680
  } else if (enableByPassLogger && !enableProxy && proxyUrl) {
1584
- logger6.info(
1681
+ logger7.info(
1585
1682
  `[\u4EE3\u7406\u672A\u542F\u7528] enable_proxy=false \u4E14 proxy_url \u5DF2\u914D\u7F6E`
1586
1683
  );
1587
1684
  }
@@ -1599,7 +1696,7 @@ var Launch = {
1599
1696
  const requestUrl = req.url();
1600
1697
  const matched = findMatchedByPassRule(byPassRules, requestUrl);
1601
1698
  if (!matched || !matched.rule) return;
1602
- logger6.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${req.resourceType()} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
1699
+ logger7.info(`[\u76F4\u8FDE\u547D\u4E2D] \u89C4\u5219=${matched.rule.pattern} \u57DF\u540D=${matched.hostname} \u8D44\u6E90\u7C7B\u578B=${req.resourceType()} \u65B9\u6CD5=${req.method()} \u5730\u5740=${requestUrl}`);
1603
1700
  };
1604
1701
  page.on("request", requestHandler);
1605
1702
  return recommendedGotoOptions;
@@ -1618,7 +1715,7 @@ var Launch = {
1618
1715
  // src/live-view.js
1619
1716
  var import_express = __toESM(require("express"), 1);
1620
1717
  var import_apify = require("apify");
1621
- var logger7 = createInternalLogger("LiveView");
1718
+ var logger8 = createInternalLogger("LiveView");
1622
1719
  async function startLiveViewServer(liveViewKey) {
1623
1720
  const app = (0, import_express.default)();
1624
1721
  app.get("/", async (req, res) => {
@@ -1643,24 +1740,24 @@ async function startLiveViewServer(liveViewKey) {
1643
1740
  </html>
1644
1741
  `);
1645
1742
  } catch (error) {
1646
- logger7.fail("Live View Server", error);
1743
+ logger8.fail("Live View Server", error);
1647
1744
  res.status(500).send(`\u65E0\u6CD5\u52A0\u8F7D\u5C4F\u5E55\u622A\u56FE: ${error.message}`);
1648
1745
  }
1649
1746
  });
1650
1747
  const port = process.env.APIFY_CONTAINER_PORT || 4321;
1651
1748
  app.listen(port, () => {
1652
- logger7.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
1749
+ logger8.success("startLiveViewServer", `\u76D1\u542C\u7AEF\u53E3 ${port}`);
1653
1750
  });
1654
1751
  }
1655
1752
  async function takeLiveScreenshot(liveViewKey, page, logMessage) {
1656
1753
  try {
1657
- const buffer = await page.screenshot({ type: "png" });
1754
+ const buffer = await capturePageScreenshot(page, { type: "png" });
1658
1755
  await import_apify.Actor.setValue(liveViewKey, buffer, { contentType: "image/png" });
1659
1756
  if (logMessage) {
1660
- logger7.info(`(\u622A\u56FE): ${logMessage}`);
1757
+ logger8.info(`(\u622A\u56FE): ${logMessage}`);
1661
1758
  }
1662
1759
  } catch (e) {
1663
- logger7.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
1760
+ logger8.warn(`\u65E0\u6CD5\u6355\u83B7 Live View \u5C4F\u5E55\u622A\u56FE: ${e.message}`);
1664
1761
  }
1665
1762
  }
1666
1763
  var useLiveView = (liveViewKey = PresetOfLiveViewKey) => {
@@ -1679,7 +1776,7 @@ var LiveView = {
1679
1776
 
1680
1777
  // src/captcha-monitor.js
1681
1778
  var import_uuid = require("uuid");
1682
- var logger8 = createInternalLogger("Captcha");
1779
+ var logger9 = createInternalLogger("Captcha");
1683
1780
  function useCaptchaMonitor(page, options) {
1684
1781
  const { domSelector, urlPattern, onDetected } = options;
1685
1782
  if (!domSelector && !urlPattern) {
@@ -1752,7 +1849,7 @@ function useCaptchaMonitor(page, options) {
1752
1849
  };
1753
1850
  })();
1754
1851
  }, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
1755
- logger8.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
1852
+ logger9.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528: ${domSelector}`);
1756
1853
  cleanupFns.push(async () => {
1757
1854
  try {
1758
1855
  await page.evaluate((name) => {
@@ -1775,14 +1872,14 @@ function useCaptchaMonitor(page, options) {
1775
1872
  }
1776
1873
  };
1777
1874
  page.on("framenavigated", frameHandler);
1778
- logger8.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
1875
+ logger9.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528: ${urlPattern}`);
1779
1876
  cleanupFns.push(async () => {
1780
1877
  page.off("framenavigated", frameHandler);
1781
1878
  });
1782
1879
  }
1783
1880
  return {
1784
1881
  stop: async () => {
1785
- logger8.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
1882
+ logger9.info("useCaptchaMonitor", "\u6B63\u5728\u505C\u6B62\u76D1\u63A7...");
1786
1883
  for (const fn of cleanupFns) {
1787
1884
  await fn();
1788
1885
  }
@@ -1797,7 +1894,7 @@ var Captcha = {
1797
1894
  // src/sse.js
1798
1895
  var import_https = __toESM(require("https"), 1);
1799
1896
  var import_url = require("url");
1800
- var logger9 = createInternalLogger("Sse");
1897
+ var logger10 = createInternalLogger("Sse");
1801
1898
  var Sse = {
1802
1899
  /**
1803
1900
  * 解析 SSE 流文本
@@ -1816,11 +1913,11 @@ var Sse = {
1816
1913
  events.push(JSON.parse(jsonContent));
1817
1914
  }
1818
1915
  } catch (e) {
1819
- logger9.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
1916
+ logger10.debug("parseSseStream", `JSON \u89E3\u6790\u5931\u8D25: ${e.message}, line: ${line.substring(0, 100)}...`);
1820
1917
  }
1821
1918
  }
1822
1919
  }
1823
- logger9.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
1920
+ logger10.success("parseSseStream", `\u89E3\u6790\u5B8C\u6210, events \u6570\u91CF: ${events.length}`);
1824
1921
  return events;
1825
1922
  },
1826
1923
  /**
@@ -1870,7 +1967,7 @@ var Sse = {
1870
1967
  if (!autoUnroute) return;
1871
1968
  if (unrouteRequested) return;
1872
1969
  unrouteRequested = true;
1873
- logger9.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
1970
+ logger10.info("[MITM] autoUnroute: \u53D6\u6D88\u540E\u7EED\u62E6\u622A");
1874
1971
  page.unroute(urlPattern, routeHandler).catch(() => {
1875
1972
  });
1876
1973
  };
@@ -1890,19 +1987,19 @@ var Sse = {
1890
1987
  };
1891
1988
  const routeHandler = async (route) => {
1892
1989
  if (firstMatchOnly && hasMatchedOnce) {
1893
- logger9.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
1990
+ logger10.info(`[MITM] firstMatchOnly: \u653E\u884C\u540E\u7EED\u8BF7\u6C42: ${route.request().url()}`);
1894
1991
  route.continue().catch(() => {
1895
1992
  });
1896
1993
  return;
1897
1994
  }
1898
1995
  if (firstMatchOnly && !hasMatchedOnce) {
1899
1996
  hasMatchedOnce = true;
1900
- logger9.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
1997
+ logger10.info("[MITM] firstMatchOnly: \u547D\u4E2D\u9996\u4E2A\u8BF7\u6C42\uFF0C\u53D6\u6D88\u540E\u7EED\u62E6\u622A");
1901
1998
  page.unroute(urlPattern, routeHandler).catch(() => {
1902
1999
  });
1903
2000
  }
1904
2001
  const request = route.request();
1905
- logger9.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
2002
+ logger10.info(`[MITM] \u5DF2\u62E6\u622A\u8BF7\u6C42: ${request.url()}`);
1906
2003
  try {
1907
2004
  const headers = await request.allHeaders();
1908
2005
  const postData = request.postData();
@@ -1927,7 +2024,7 @@ var Sse = {
1927
2024
  clearTimeout(initialTimer);
1928
2025
  initialTimer = null;
1929
2026
  }
1930
- logger9.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
2027
+ logger10.debug("[Intercept] \u5DF2\u63A5\u6536\u521D\u59CB\u6570\u636E");
1931
2028
  }
1932
2029
  chunks.push(chunk);
1933
2030
  const textChunk = chunk.toString("utf-8");
@@ -1936,18 +2033,18 @@ var Sse = {
1936
2033
  try {
1937
2034
  onData(textChunk, safeResolve, accumulatedText);
1938
2035
  } catch (e) {
1939
- logger9.fail(`onData \u9519\u8BEF`, e);
2036
+ logger10.fail(`onData \u9519\u8BEF`, e);
1940
2037
  }
1941
2038
  }
1942
2039
  });
1943
2040
  res.on("end", () => {
1944
- logger9.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
2041
+ logger10.info("[MITM] \u4E0A\u6E38\u54CD\u5E94\u7ED3\u675F");
1945
2042
  clearAllTimers();
1946
2043
  if (onEnd) {
1947
2044
  try {
1948
2045
  onEnd(accumulatedText, safeResolve);
1949
2046
  } catch (e) {
1950
- logger9.fail(`onEnd \u9519\u8BEF`, e);
2047
+ logger10.fail(`onEnd \u9519\u8BEF`, e);
1951
2048
  }
1952
2049
  } else if (!onData) {
1953
2050
  safeResolve(accumulatedText);
@@ -2028,7 +2125,7 @@ var Sse = {
2028
2125
 
2029
2126
  // src/mutation.js
2030
2127
  var import_uuid2 = require("uuid");
2031
- var logger10 = createInternalLogger("Mutation");
2128
+ var logger11 = createInternalLogger("Mutation");
2032
2129
  var MUTATION_MONITOR_MODE = Object.freeze({
2033
2130
  Added: "added",
2034
2131
  Changed: "changed",
@@ -2061,14 +2158,14 @@ var Mutation = {
2061
2158
  const stableTime = options.stableTime ?? 5 * 1e3;
2062
2159
  const timeout = options.timeout ?? 120 * 1e3;
2063
2160
  const onMutation = options.onMutation;
2064
- logger10.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
2161
+ logger11.start("waitForStable", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, \u7A33\u5B9A\u65F6\u95F4=${stableTime}ms`);
2065
2162
  if (initialTimeout > 0) {
2066
2163
  const selectorQuery = selectorList.join(",");
2067
2164
  try {
2068
2165
  await page.waitForSelector(selectorQuery, { timeout: initialTimeout });
2069
- logger10.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
2166
+ logger11.info(`waitForStable \u5DF2\u68C0\u6D4B\u5230\u5143\u7D20: ${selectorQuery}`);
2070
2167
  } catch (e) {
2071
- logger10.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
2168
+ logger11.warning(`waitForStable \u521D\u59CB\u7B49\u5F85\u8D85\u65F6 (${initialTimeout}ms): ${selectorQuery}`);
2072
2169
  throw e;
2073
2170
  }
2074
2171
  }
@@ -2084,7 +2181,7 @@ var Mutation = {
2084
2181
  return "__CONTINUE__";
2085
2182
  }
2086
2183
  });
2087
- logger10.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
2184
+ logger11.info("waitForStable \u5DF2\u542F\u7528 onMutation \u56DE\u8C03");
2088
2185
  } catch (e) {
2089
2186
  }
2090
2187
  }
@@ -2199,9 +2296,9 @@ var Mutation = {
2199
2296
  { selectorList, stableTime, timeout, callbackName, hasCallback: !!onMutation }
2200
2297
  );
2201
2298
  if (result.mutationCount === 0 && result.stableTime === 0) {
2202
- logger10.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
2299
+ logger11.warning("waitForStable \u672A\u627E\u5230\u53EF\u76D1\u63A7\u7684\u5143\u7D20");
2203
2300
  }
2204
- logger10.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
2301
+ logger11.success("waitForStable", `DOM \u7A33\u5B9A, \u603B\u5171 ${result.mutationCount} \u6B21\u53D8\u5316${result.wasPaused ? ", \u66FE\u6682\u505C\u8BA1\u65F6" : ""}`);
2205
2302
  return result;
2206
2303
  },
2207
2304
  /**
@@ -2221,7 +2318,7 @@ var Mutation = {
2221
2318
  const onMutation = options.onMutation;
2222
2319
  const rawMode = String(options.mode || MUTATION_MONITOR_MODE.Added).toLowerCase();
2223
2320
  const mode = [MUTATION_MONITOR_MODE.Added, MUTATION_MONITOR_MODE.Changed, MUTATION_MONITOR_MODE.All].includes(rawMode) ? rawMode : MUTATION_MONITOR_MODE.Added;
2224
- logger10.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
2321
+ logger11.start("useMonitor", `\u76D1\u63A7 ${selectorList.length} \u4E2A\u9009\u62E9\u5668, mode=${mode}`);
2225
2322
  const monitorKey = generateKey("pk_mon");
2226
2323
  const callbackName = generateKey("pk_mon_cb");
2227
2324
  const cleanerName = generateKey("pk_mon_clean");
@@ -2364,7 +2461,7 @@ var Mutation = {
2364
2461
  return total;
2365
2462
  };
2366
2463
  }, { selectorList, monitorKey, callbackName, cleanerName, hasCallback: !!onMutation, mode });
2367
- logger10.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
2464
+ logger11.success("useMonitor", "\u76D1\u63A7\u5668\u5DF2\u542F\u52A8");
2368
2465
  return {
2369
2466
  stop: async () => {
2370
2467
  let totalMutations = 0;
@@ -2377,7 +2474,7 @@ var Mutation = {
2377
2474
  }, cleanerName);
2378
2475
  } catch (e) {
2379
2476
  }
2380
- logger10.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
2477
+ logger11.success("useMonitor.stop", `\u76D1\u63A7\u5DF2\u505C\u6B62, \u5171 ${totalMutations} \u6B21\u53D8\u5316`);
2381
2478
  return { totalMutations };
2382
2479
  }
2383
2480
  };
@@ -3246,7 +3343,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
3246
3343
  };
3247
3344
  var getDefaultBaseLogger = () => createBaseLogger("");
3248
3345
  var Logger = {
3249
- setLogger: (logger12) => setDefaultLogger(logger12),
3346
+ setLogger: (logger13) => setDefaultLogger(logger13),
3250
3347
  info: (message) => getDefaultBaseLogger().info(message),
3251
3348
  success: (message) => getDefaultBaseLogger().success(message),
3252
3349
  warning: (message) => getDefaultBaseLogger().warning(message),
@@ -3254,16 +3351,16 @@ var Logger = {
3254
3351
  error: (message) => getDefaultBaseLogger().error(message),
3255
3352
  debug: (message) => getDefaultBaseLogger().debug(message),
3256
3353
  start: (message) => getDefaultBaseLogger().start(message),
3257
- useTemplate: (logger12) => {
3258
- if (logger12) return createTemplateLogger(createBaseLogger("", logger12));
3354
+ useTemplate: (logger13) => {
3355
+ if (logger13) return createTemplateLogger(createBaseLogger("", logger13));
3259
3356
  return createTemplateLogger();
3260
3357
  }
3261
3358
  };
3262
3359
 
3263
3360
  // src/share.js
3264
3361
  var import_delay2 = __toESM(require("delay"), 1);
3265
- var logger11 = createInternalLogger("Share");
3266
- var DEFAULT_TIMEOUT_MS = 50 * 1e3;
3362
+ var logger12 = createInternalLogger("Share");
3363
+ var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
3267
3364
  var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
3268
3365
  var DEFAULT_POLL_INTERVAL_MS = 120;
3269
3366
  var normalizePrefix = (value) => value == null ? void 0 : String(value).trim();
@@ -3382,7 +3479,7 @@ var createDomShareMonitor = async (page, options = {}) => {
3382
3479
  const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
3383
3480
  const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
3384
3481
  let matched = false;
3385
- logger11.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
3482
+ logger12.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
3386
3483
  const monitor = await Mutation.useMonitor(page, selectors, {
3387
3484
  mode,
3388
3485
  onMutation: (context = {}) => {
@@ -3400,12 +3497,12 @@ ${text}`;
3400
3497
  });
3401
3498
  }
3402
3499
  if (mutationCount <= 5 || mutationCount % 50 === 0) {
3403
- logger11.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
3500
+ logger12.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
3404
3501
  }
3405
3502
  const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
3406
3503
  if (!candidate) return;
3407
3504
  matched = true;
3408
- logger11.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
3505
+ logger12.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
3409
3506
  if (onMatch) {
3410
3507
  onMatch({
3411
3508
  link: candidate,
@@ -3421,7 +3518,7 @@ ${text}`;
3421
3518
  return {
3422
3519
  stop: async () => {
3423
3520
  const result = await monitor.stop();
3424
- logger11.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
3521
+ logger12.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
3425
3522
  return result;
3426
3523
  }
3427
3524
  };
@@ -3444,7 +3541,7 @@ var Share = {
3444
3541
  */
3445
3542
  async captureLink(page, options = {}) {
3446
3543
  const share = normalizeShare(options.share);
3447
- const timeoutMs = Math.max(0, Number(options.timeoutMs ?? DEFAULT_TIMEOUT_MS) || 0);
3544
+ const timeoutMs = Math.max(0, Number(options.timeoutMs ?? DEFAULT_TIMEOUT_MS2) || 0);
3448
3545
  const payloadSnapshotMaxLen = options.payloadSnapshotMaxLen ?? DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN;
3449
3546
  const domSelectors = options.domSelectors ?? "html";
3450
3547
  const domMode = options.domMode ?? Mutation.Mode.All;
@@ -3461,8 +3558,8 @@ var Share = {
3461
3558
  if (share.mode === "response" && apiMatchers.length === 0) {
3462
3559
  throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
3463
3560
  }
3464
- logger11.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
3465
- logger11.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
3561
+ logger12.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
3562
+ logger12.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
3466
3563
  const stats = {
3467
3564
  actionTimedOut: false,
3468
3565
  domMutationCount: 0,
@@ -3487,7 +3584,7 @@ var Share = {
3487
3584
  link: validated,
3488
3585
  payloadText: String(payloadText || "")
3489
3586
  };
3490
- logger11.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
3587
+ logger12.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
3491
3588
  return true;
3492
3589
  };
3493
3590
  const resolveResponseCandidate = (responseText) => {
@@ -3522,7 +3619,7 @@ var Share = {
3522
3619
  try {
3523
3620
  await monitor.stop();
3524
3621
  } catch (error) {
3525
- logger11.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
3622
+ logger12.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
3526
3623
  }
3527
3624
  };
3528
3625
  const onResponse = async (response) => {
@@ -3535,29 +3632,29 @@ var Share = {
3535
3632
  stats.responseSampleUrls.push(url);
3536
3633
  }
3537
3634
  if (stats.responseObserved <= 5) {
3538
- logger11.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
3635
+ logger12.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
3539
3636
  }
3540
3637
  if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
3541
3638
  stats.responseMatched += 1;
3542
3639
  stats.lastMatchedUrl = url;
3543
- logger11.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
3640
+ logger12.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
3544
3641
  const text = await response.text();
3545
3642
  const hit = resolveResponseCandidate(text);
3546
3643
  if (!hit?.link) {
3547
3644
  if (stats.responseMatched <= 3) {
3548
- logger11.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
3645
+ logger12.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
3549
3646
  }
3550
3647
  return;
3551
3648
  }
3552
3649
  stats.responseResolved += 1;
3553
- logger11.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
3650
+ logger12.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
3554
3651
  setCandidate("response", hit.link, hit.payloadText);
3555
3652
  } catch (error) {
3556
- logger11.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
3653
+ logger12.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
3557
3654
  }
3558
3655
  };
3559
3656
  if (share.mode === "dom") {
3560
- logger11.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
3657
+ logger12.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
3561
3658
  domMonitor = await createDomShareMonitor(page, {
3562
3659
  prefix: share.prefix,
3563
3660
  selectors: domSelectors,
@@ -3572,14 +3669,14 @@ var Share = {
3572
3669
  });
3573
3670
  }
3574
3671
  if (share.mode === "response") {
3575
- logger11.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
3672
+ logger12.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
3576
3673
  page.on("response", onResponse);
3577
3674
  }
3578
3675
  const deadline = Date.now() + timeoutMs;
3579
3676
  const getRemainingMs = () => Math.max(0, deadline - Date.now());
3580
3677
  try {
3581
3678
  const actionTimeout = getRemainingMs();
3582
- logger11.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
3679
+ logger12.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
3583
3680
  if (actionTimeout > 0) {
3584
3681
  let timer = null;
3585
3682
  let actionError = null;
@@ -3593,21 +3690,21 @@ var Share = {
3593
3690
  const actionResult = await Promise.race([actionPromise, timeoutPromise]);
3594
3691
  if (timer) clearTimeout(timer);
3595
3692
  if (actionResult === "__ACTION_ERROR__") {
3596
- logger11.fail("captureLink.performActions", actionError);
3693
+ logger12.fail("captureLink.performActions", actionError);
3597
3694
  throw actionError;
3598
3695
  }
3599
3696
  if (actionResult === "__ACTION_TIMEOUT__") {
3600
3697
  stats.actionTimedOut = true;
3601
- logger11.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
3698
+ logger12.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
3602
3699
  } else {
3603
- logger11.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
3700
+ logger12.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
3604
3701
  }
3605
3702
  }
3606
3703
  let nextProgressLogTs = Date.now() + 3e3;
3607
3704
  while (true) {
3608
3705
  const selected = share.mode === "dom" ? candidates.dom : candidates.response;
3609
3706
  if (selected?.link) {
3610
- logger11.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
3707
+ logger12.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
3611
3708
  return {
3612
3709
  link: selected.link,
3613
3710
  payloadText: selected.payloadText,
@@ -3619,7 +3716,7 @@ var Share = {
3619
3716
  if (remaining <= 0) break;
3620
3717
  const now = Date.now();
3621
3718
  if (now >= nextProgressLogTs) {
3622
- logger11.info(
3719
+ logger12.info(
3623
3720
  `captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
3624
3721
  );
3625
3722
  nextProgressLogTs = now + 5e3;
@@ -3627,11 +3724,11 @@ var Share = {
3627
3724
  await (0, import_delay2.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
3628
3725
  }
3629
3726
  if (share.mode === "response" && stats.responseMatched === 0) {
3630
- logger11.warning(
3727
+ logger12.warning(
3631
3728
  `\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
3632
3729
  );
3633
3730
  }
3634
- logger11.warning(
3731
+ logger12.warning(
3635
3732
  `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"}`
3636
3733
  );
3637
3734
  return {
@@ -3643,7 +3740,7 @@ var Share = {
3643
3740
  } finally {
3644
3741
  if (share.mode === "response") {
3645
3742
  page.off("response", onResponse);
3646
- logger11.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
3743
+ logger12.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
3647
3744
  }
3648
3745
  await stopDomMonitor();
3649
3746
  }
@@ -3691,9 +3788,10 @@ var Share = {
3691
3788
  height: targetHeight
3692
3789
  });
3693
3790
  await (0, import_delay2.default)(1e3);
3694
- const buffer_ = await page.screenshot({
3791
+ const buffer_ = await capturePageScreenshot(page, {
3695
3792
  fullPage: true,
3696
- type: "png"
3793
+ type: "png",
3794
+ maxClipHeight: targetHeight
3697
3795
  });
3698
3796
  return buffer_.toString("base64");
3699
3797
  } finally {