@skrillex1224/playwright-toolkit 2.1.211 → 2.1.213
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +291 -61
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +291 -61
- package/dist/index.js.map +3 -3
- package/index.d.ts +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -223,7 +223,7 @@ const image3 = await Share.captureScreen(page, {
|
|
|
223
223
|
watermarkify: {
|
|
224
224
|
query: '你好',
|
|
225
225
|
timezoneOffsetHours: 8,
|
|
226
|
-
// 默认会在同一浏览器上下文里访问
|
|
226
|
+
// 默认会在同一浏览器上下文里访问 https://myip.ipip.net/json 补充 IP / Loc,超时默认 10000ms
|
|
227
227
|
},
|
|
228
228
|
});
|
|
229
229
|
|
package/dist/index.cjs
CHANGED
|
@@ -350,18 +350,18 @@ var fallbackLog = {
|
|
|
350
350
|
error: (...args) => console.error(...args),
|
|
351
351
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
352
352
|
};
|
|
353
|
-
var resolveLogMethod = (
|
|
354
|
-
if (
|
|
355
|
-
return
|
|
353
|
+
var resolveLogMethod = (logger13, name) => {
|
|
354
|
+
if (logger13 && typeof logger13[name] === "function") {
|
|
355
|
+
return logger13[name].bind(logger13);
|
|
356
356
|
}
|
|
357
|
-
if (name === "warning" &&
|
|
358
|
-
return
|
|
357
|
+
if (name === "warning" && logger13 && typeof logger13.warn === "function") {
|
|
358
|
+
return logger13.warn.bind(logger13);
|
|
359
359
|
}
|
|
360
360
|
return fallbackLog[name];
|
|
361
361
|
};
|
|
362
362
|
var defaultLogger = null;
|
|
363
|
-
var setDefaultLogger = (
|
|
364
|
-
defaultLogger =
|
|
363
|
+
var setDefaultLogger = (logger13) => {
|
|
364
|
+
defaultLogger = logger13;
|
|
365
365
|
};
|
|
366
366
|
var resolveLogger = (explicitLogger) => {
|
|
367
367
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -388,8 +388,8 @@ var colorize = (text, color) => {
|
|
|
388
388
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
389
389
|
const name = prefix ? String(prefix) : "";
|
|
390
390
|
const dispatch = (methodName, icon, message, color) => {
|
|
391
|
-
const
|
|
392
|
-
const logFn = resolveLogMethod(
|
|
391
|
+
const logger13 = resolveLogger(explicitLogger);
|
|
392
|
+
const logFn = resolveLogMethod(logger13, methodName);
|
|
393
393
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
394
394
|
const line = formatLine(name, icon, message);
|
|
395
395
|
const coloredLine = colorize(line, color);
|
|
@@ -4569,7 +4569,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
4569
4569
|
};
|
|
4570
4570
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
4571
4571
|
var Logger = {
|
|
4572
|
-
setLogger: (
|
|
4572
|
+
setLogger: (logger13) => setDefaultLogger(logger13),
|
|
4573
4573
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
4574
4574
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
4575
4575
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -4577,8 +4577,8 @@ var Logger = {
|
|
|
4577
4577
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
4578
4578
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
4579
4579
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
4580
|
-
useTemplate: (
|
|
4581
|
-
if (
|
|
4580
|
+
useTemplate: (logger13) => {
|
|
4581
|
+
if (logger13) return createTemplateLogger(createBaseLogger("", logger13));
|
|
4582
4582
|
return createTemplateLogger();
|
|
4583
4583
|
}
|
|
4584
4584
|
};
|
|
@@ -4587,7 +4587,6 @@ var Logger = {
|
|
|
4587
4587
|
var import_delay2 = __toESM(require("delay"), 1);
|
|
4588
4588
|
|
|
4589
4589
|
// src/internals/watermarkify.js
|
|
4590
|
-
var import_sharp = __toESM(require("sharp"), 1);
|
|
4591
4590
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
4592
4591
|
var DEFAULT_RESOLVER_TIMEOUT_MS = 180;
|
|
4593
4592
|
var DEFAULT_IP_LOOKUP_TIMEOUT_MS = 1e4;
|
|
@@ -4596,7 +4595,7 @@ var DEFAULT_WATERMARK_ROTATE_DEG = -16;
|
|
|
4596
4595
|
var DEFAULT_WATERMARK_CELL_WIDTH = 860;
|
|
4597
4596
|
var DEFAULT_WATERMARK_CELL_HEIGHT = 330;
|
|
4598
4597
|
var DEFAULT_STRIP_LOGO_URL = "https://static.heartbitai.com/geo/icon/favicon.png";
|
|
4599
|
-
var DEFAULT_IP_LOOKUP_URL = "
|
|
4598
|
+
var DEFAULT_IP_LOOKUP_URL = "https://myip.ipip.net/json";
|
|
4600
4599
|
var DEFAULT_LOGO_FETCH_TIMEOUT_MS = 2500;
|
|
4601
4600
|
var DEFAULT_STRIP_ONE_LINE_HEIGHT = 78;
|
|
4602
4601
|
var DEFAULT_STRIP_WRAPPED_MIN_HEIGHT = 108;
|
|
@@ -4618,6 +4617,7 @@ var DEFAULT_STRIP_LINE_HEIGHT_RATIO = 1.28;
|
|
|
4618
4617
|
var DEFAULT_STRIP_PROMPT_MAX_LINES = 3;
|
|
4619
4618
|
var DEFAULT_STRIP_CONTENT_SAFE_PADDING_X = 12;
|
|
4620
4619
|
var DEFAULT_STRIP_TEXT_WIDTH_SAFETY = 10;
|
|
4620
|
+
var DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT = 1200;
|
|
4621
4621
|
var WEAK_LOCATION_VALUES = /* @__PURE__ */ new Set(["cn", "\u4E2D\u56FD"]);
|
|
4622
4622
|
var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
4623
4623
|
/(?:中国)?移动$/i,
|
|
@@ -4643,6 +4643,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
4643
4643
|
];
|
|
4644
4644
|
var cachedStripLogoSrcPromise = null;
|
|
4645
4645
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
4646
|
+
var logger11 = createInternalLogger("Watermarkify");
|
|
4646
4647
|
var normalizeText = (value) => String(value || "").trim();
|
|
4647
4648
|
var toInline = (value, maxLen = 200) => {
|
|
4648
4649
|
const text = normalizeText(value);
|
|
@@ -4710,18 +4711,26 @@ var pickHeaderValue = async (response, names = []) => {
|
|
|
4710
4711
|
}
|
|
4711
4712
|
return "";
|
|
4712
4713
|
};
|
|
4713
|
-
var
|
|
4714
|
+
var parseIpIpJsonResponse = (rawText) => {
|
|
4714
4715
|
const text = normalizeWhitespace(rawText);
|
|
4715
|
-
if (!text)
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4716
|
+
if (!text || !text.startsWith("{") && !text.startsWith("[")) {
|
|
4717
|
+
return null;
|
|
4718
|
+
}
|
|
4719
|
+
try {
|
|
4720
|
+
const payload = JSON.parse(text);
|
|
4721
|
+
const ip = toInline(payload?.data?.ip || payload?.ip, 80);
|
|
4722
|
+
const locationParts = Array.isArray(payload?.data?.location) ? payload.data.location.map((item) => normalizeWhitespace(item)).filter(Boolean) : [];
|
|
4723
|
+
const location = toInline(
|
|
4724
|
+
stripLocationNetworkSuffix(locationParts.join(" ")),
|
|
4725
|
+
80
|
|
4726
|
+
);
|
|
4727
|
+
if (!ip && !location) {
|
|
4728
|
+
return null;
|
|
4729
|
+
}
|
|
4730
|
+
return { ip, location };
|
|
4731
|
+
} catch {
|
|
4722
4732
|
return null;
|
|
4723
4733
|
}
|
|
4724
|
-
return { ip, location };
|
|
4725
4734
|
};
|
|
4726
4735
|
var fillEnrichment = (target, source) => {
|
|
4727
4736
|
if (!target || !source || typeof source !== "object") {
|
|
@@ -4871,10 +4880,16 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
4871
4880
|
if (!resolved || typeof resolved !== "object") {
|
|
4872
4881
|
return null;
|
|
4873
4882
|
}
|
|
4874
|
-
|
|
4883
|
+
const enrichment = {
|
|
4875
4884
|
ip: toInline(resolved.ip, 80),
|
|
4876
4885
|
location: toInline(resolved.location, 80)
|
|
4877
4886
|
};
|
|
4887
|
+
if (enrichment.ip || enrichment.location) {
|
|
4888
|
+
logger11.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
4889
|
+
} else {
|
|
4890
|
+
logger11.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
4891
|
+
}
|
|
4892
|
+
return enrichment;
|
|
4878
4893
|
} finally {
|
|
4879
4894
|
controller?.abort();
|
|
4880
4895
|
}
|
|
@@ -4925,12 +4940,205 @@ var openProbePage = async (page) => {
|
|
|
4925
4940
|
}
|
|
4926
4941
|
return null;
|
|
4927
4942
|
};
|
|
4943
|
+
var readPngDimensions = (buffer) => {
|
|
4944
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 24) {
|
|
4945
|
+
return { width: 0, height: 0 };
|
|
4946
|
+
}
|
|
4947
|
+
const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
4948
|
+
for (let index = 0; index < pngSignature.length; index += 1) {
|
|
4949
|
+
if (buffer[index] !== pngSignature[index]) {
|
|
4950
|
+
return { width: 0, height: 0 };
|
|
4951
|
+
}
|
|
4952
|
+
}
|
|
4953
|
+
return {
|
|
4954
|
+
width: buffer.readUInt32BE(16),
|
|
4955
|
+
height: buffer.readUInt32BE(20)
|
|
4956
|
+
};
|
|
4957
|
+
};
|
|
4958
|
+
var readJpegDimensions = (buffer) => {
|
|
4959
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 4 || buffer[0] !== 255 || buffer[1] !== 216) {
|
|
4960
|
+
return { width: 0, height: 0 };
|
|
4961
|
+
}
|
|
4962
|
+
let offset = 2;
|
|
4963
|
+
while (offset + 9 <= buffer.length) {
|
|
4964
|
+
if (buffer[offset] !== 255) {
|
|
4965
|
+
offset += 1;
|
|
4966
|
+
continue;
|
|
4967
|
+
}
|
|
4968
|
+
const marker = buffer[offset + 1];
|
|
4969
|
+
offset += 2;
|
|
4970
|
+
if (marker === 216 || marker === 217) {
|
|
4971
|
+
continue;
|
|
4972
|
+
}
|
|
4973
|
+
if (marker === 218) {
|
|
4974
|
+
break;
|
|
4975
|
+
}
|
|
4976
|
+
if (offset + 2 > buffer.length) {
|
|
4977
|
+
break;
|
|
4978
|
+
}
|
|
4979
|
+
const segmentLength = buffer.readUInt16BE(offset);
|
|
4980
|
+
if (segmentLength < 2 || offset + segmentLength > buffer.length) {
|
|
4981
|
+
break;
|
|
4982
|
+
}
|
|
4983
|
+
const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
|
|
4984
|
+
if (isStartOfFrame && offset + 7 <= buffer.length) {
|
|
4985
|
+
return {
|
|
4986
|
+
height: buffer.readUInt16BE(offset + 3),
|
|
4987
|
+
width: buffer.readUInt16BE(offset + 5)
|
|
4988
|
+
};
|
|
4989
|
+
}
|
|
4990
|
+
offset += segmentLength;
|
|
4991
|
+
}
|
|
4992
|
+
return { width: 0, height: 0 };
|
|
4993
|
+
};
|
|
4994
|
+
var readImageInfo = (buffer) => {
|
|
4995
|
+
const png = readPngDimensions(buffer);
|
|
4996
|
+
if (png.width && png.height) {
|
|
4997
|
+
return {
|
|
4998
|
+
mimeType: "image/png",
|
|
4999
|
+
width: png.width,
|
|
5000
|
+
height: png.height
|
|
5001
|
+
};
|
|
5002
|
+
}
|
|
5003
|
+
const jpeg = readJpegDimensions(buffer);
|
|
5004
|
+
if (jpeg.width && jpeg.height) {
|
|
5005
|
+
return {
|
|
5006
|
+
mimeType: "image/jpeg",
|
|
5007
|
+
width: jpeg.width,
|
|
5008
|
+
height: jpeg.height
|
|
5009
|
+
};
|
|
5010
|
+
}
|
|
5011
|
+
return {
|
|
5012
|
+
mimeType: "",
|
|
5013
|
+
width: 0,
|
|
5014
|
+
height: 0
|
|
5015
|
+
};
|
|
5016
|
+
};
|
|
5017
|
+
var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height }) => {
|
|
5018
|
+
const safeWidth = Math.max(1, Number(width) || 1);
|
|
5019
|
+
const safeHeight = Math.max(1, Number(height) || 1);
|
|
5020
|
+
return `
|
|
5021
|
+
<!doctype html>
|
|
5022
|
+
<html lang="zh-CN">
|
|
5023
|
+
<head>
|
|
5024
|
+
<meta charset="utf-8" />
|
|
5025
|
+
<style>
|
|
5026
|
+
html, body {
|
|
5027
|
+
margin: 0;
|
|
5028
|
+
padding: 0;
|
|
5029
|
+
width: ${safeWidth}px;
|
|
5030
|
+
height: ${safeHeight}px;
|
|
5031
|
+
overflow: hidden;
|
|
5032
|
+
background: #ffffff;
|
|
5033
|
+
}
|
|
5034
|
+
|
|
5035
|
+
body {
|
|
5036
|
+
position: relative;
|
|
5037
|
+
}
|
|
5038
|
+
|
|
5039
|
+
#pk-stage {
|
|
5040
|
+
position: relative;
|
|
5041
|
+
width: ${safeWidth}px;
|
|
5042
|
+
height: ${safeHeight}px;
|
|
5043
|
+
overflow: hidden;
|
|
5044
|
+
}
|
|
5045
|
+
|
|
5046
|
+
#pk-base-image {
|
|
5047
|
+
position: absolute;
|
|
5048
|
+
inset: 0;
|
|
5049
|
+
display: block;
|
|
5050
|
+
width: ${safeWidth}px;
|
|
5051
|
+
height: ${safeHeight}px;
|
|
5052
|
+
}
|
|
5053
|
+
|
|
5054
|
+
#pk-overlay {
|
|
5055
|
+
position: absolute;
|
|
5056
|
+
inset: 0;
|
|
5057
|
+
width: ${safeWidth}px;
|
|
5058
|
+
height: ${safeHeight}px;
|
|
5059
|
+
pointer-events: none;
|
|
5060
|
+
}
|
|
5061
|
+
</style>
|
|
5062
|
+
</head>
|
|
5063
|
+
<body>
|
|
5064
|
+
<div id="pk-stage">
|
|
5065
|
+
<img id="pk-base-image" src="${escapeHtmlAttribute(imageSrc)}" alt="" />
|
|
5066
|
+
<div id="pk-overlay">${overlaySvg}</div>
|
|
5067
|
+
</div>
|
|
5068
|
+
</body>
|
|
5069
|
+
</html>
|
|
5070
|
+
`;
|
|
5071
|
+
};
|
|
5072
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
|
|
5073
|
+
if (!page || typeof page.context !== "function") {
|
|
5074
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
5075
|
+
return buffer;
|
|
5076
|
+
}
|
|
5077
|
+
const renderScope = await openProbePage(page);
|
|
5078
|
+
if (!renderScope?.page) {
|
|
5079
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
5080
|
+
return buffer;
|
|
5081
|
+
}
|
|
5082
|
+
try {
|
|
5083
|
+
const renderPage = renderScope.page;
|
|
5084
|
+
const safeWidth = Math.max(1, Number(imageInfo.width) || 1);
|
|
5085
|
+
const safeHeight = Math.max(1, Number(imageInfo.height) || 1);
|
|
5086
|
+
const viewportHeight = Math.max(
|
|
5087
|
+
1,
|
|
5088
|
+
Math.min(safeHeight, DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT)
|
|
5089
|
+
);
|
|
5090
|
+
await renderPage.setViewportSize({
|
|
5091
|
+
width: safeWidth,
|
|
5092
|
+
height: viewportHeight
|
|
5093
|
+
}).catch(() => {
|
|
5094
|
+
});
|
|
5095
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
5096
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
5097
|
+
overlaySvg,
|
|
5098
|
+
width: safeWidth,
|
|
5099
|
+
height: safeHeight
|
|
5100
|
+
}), {
|
|
5101
|
+
waitUntil: "load"
|
|
5102
|
+
});
|
|
5103
|
+
await renderPage.waitForFunction(() => {
|
|
5104
|
+
const image = document.getElementById("pk-base-image");
|
|
5105
|
+
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
5106
|
+
}, {
|
|
5107
|
+
timeout: 5e3
|
|
5108
|
+
}).catch(() => {
|
|
5109
|
+
});
|
|
5110
|
+
await renderPage.evaluate(async () => {
|
|
5111
|
+
if (document.fonts?.ready) {
|
|
5112
|
+
await document.fonts.ready.catch(() => {
|
|
5113
|
+
});
|
|
5114
|
+
}
|
|
5115
|
+
}).catch(() => {
|
|
5116
|
+
});
|
|
5117
|
+
const composed = await renderPage.screenshot({
|
|
5118
|
+
type: "png",
|
|
5119
|
+
fullPage: true,
|
|
5120
|
+
animations: "disabled"
|
|
5121
|
+
}).catch((error) => {
|
|
5122
|
+
logger11.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
5123
|
+
return null;
|
|
5124
|
+
});
|
|
5125
|
+
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
5126
|
+
return composed;
|
|
5127
|
+
}
|
|
5128
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
5129
|
+
return buffer;
|
|
5130
|
+
} finally {
|
|
5131
|
+
await renderScope.close().catch(() => {
|
|
5132
|
+
});
|
|
5133
|
+
}
|
|
5134
|
+
};
|
|
4928
5135
|
var resolveWithIpLookup = async (page, options = {}) => {
|
|
4929
5136
|
if (!page || typeof page.context !== "function" || options.ipLookup === false) {
|
|
4930
5137
|
return null;
|
|
4931
5138
|
}
|
|
4932
5139
|
const probeScope = await openProbePage(page);
|
|
4933
5140
|
if (!probeScope?.page) {
|
|
5141
|
+
logger11.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
4934
5142
|
return null;
|
|
4935
5143
|
}
|
|
4936
5144
|
const timeoutMs = Math.max(
|
|
@@ -4939,10 +5147,16 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
4939
5147
|
);
|
|
4940
5148
|
try {
|
|
4941
5149
|
const probePage = probeScope.page;
|
|
5150
|
+
logger11.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
4942
5151
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
4943
5152
|
waitUntil: "commit",
|
|
4944
5153
|
timeout: timeoutMs
|
|
4945
|
-
}).catch(() =>
|
|
5154
|
+
}).catch((error) => {
|
|
5155
|
+
logger11.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
5156
|
+
return null;
|
|
5157
|
+
});
|
|
5158
|
+
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
5159
|
+
const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
|
|
4946
5160
|
let rawText = "";
|
|
4947
5161
|
if (response && typeof response.text === "function") {
|
|
4948
5162
|
rawText = String(await withTimeout(
|
|
@@ -4958,8 +5172,15 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
4958
5172
|
Math.min(timeoutMs, 500)
|
|
4959
5173
|
) || "");
|
|
4960
5174
|
}
|
|
4961
|
-
|
|
4962
|
-
|
|
5175
|
+
const parsed = parseIpIpJsonResponse(rawText);
|
|
5176
|
+
if (parsed?.ip || parsed?.location) {
|
|
5177
|
+
logger11.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
5178
|
+
return parsed;
|
|
5179
|
+
}
|
|
5180
|
+
logger11.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
5181
|
+
return null;
|
|
5182
|
+
} catch (error) {
|
|
5183
|
+
logger11.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
4963
5184
|
return null;
|
|
4964
5185
|
} finally {
|
|
4965
5186
|
await probeScope.close().catch(() => {
|
|
@@ -4973,7 +5194,11 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
4973
5194
|
ip: toInline(options.ip, 80),
|
|
4974
5195
|
location: toInline(options.location, 80)
|
|
4975
5196
|
};
|
|
5197
|
+
logger11.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
4976
5198
|
if (!merged.ip || !merged.location) {
|
|
5199
|
+
if (cached?.ip || cached?.location) {
|
|
5200
|
+
logger11.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
5201
|
+
}
|
|
4977
5202
|
fillEnrichment(merged, cached);
|
|
4978
5203
|
}
|
|
4979
5204
|
if (!merged.ip || !merged.location) {
|
|
@@ -4996,10 +5221,16 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
4996
5221
|
"x-geo-country"
|
|
4997
5222
|
]), 80);
|
|
4998
5223
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
5224
|
+
logger11.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
4999
5225
|
merged.location = headerLocation || merged.location;
|
|
5000
5226
|
}
|
|
5001
5227
|
}
|
|
5002
5228
|
writeCachedEnrichment(page, merged);
|
|
5229
|
+
if (merged.ip || merged.location) {
|
|
5230
|
+
logger11.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
5231
|
+
} else {
|
|
5232
|
+
logger11.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
5233
|
+
}
|
|
5003
5234
|
return merged;
|
|
5004
5235
|
};
|
|
5005
5236
|
var buildWatermarkStamp = ({ prompt, captureTime, ip, location }) => {
|
|
@@ -5046,6 +5277,7 @@ var buildStripSegments = ({ prompt, captureTime, ip, location }) => {
|
|
|
5046
5277
|
];
|
|
5047
5278
|
};
|
|
5048
5279
|
var escapeXml = (value) => String(value || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5280
|
+
var escapeHtmlAttribute = (value) => String(value || "").replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
5049
5281
|
var estimateTextWidth = (value, fontSize = 16) => {
|
|
5050
5282
|
const text = String(value || "");
|
|
5051
5283
|
let width = 0;
|
|
@@ -5657,28 +5889,26 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
5657
5889
|
</svg>
|
|
5658
5890
|
`;
|
|
5659
5891
|
};
|
|
5660
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta) => {
|
|
5892
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
5661
5893
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
5662
5894
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
5663
5895
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
5664
5896
|
return buffer;
|
|
5665
5897
|
}
|
|
5666
|
-
const
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
const height = Math.max(1, Number(metadata?.height) || 0);
|
|
5670
|
-
if (!width || !height) {
|
|
5898
|
+
const imageInfo = readImageInfo(buffer);
|
|
5899
|
+
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
5900
|
+
logger11.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
5671
5901
|
return buffer;
|
|
5672
5902
|
}
|
|
5673
|
-
const overlaySvg = buildWatermarkifySvg(meta, width, height);
|
|
5903
|
+
const overlaySvg = buildWatermarkifySvg(meta, imageInfo.width, imageInfo.height);
|
|
5674
5904
|
if (!overlaySvg) {
|
|
5675
5905
|
return buffer;
|
|
5676
5906
|
}
|
|
5677
|
-
return await
|
|
5907
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
|
|
5678
5908
|
};
|
|
5679
5909
|
|
|
5680
5910
|
// src/share.js
|
|
5681
|
-
var
|
|
5911
|
+
var logger12 = createInternalLogger("Share");
|
|
5682
5912
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
5683
5913
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
5684
5914
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -5815,7 +6045,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
5815
6045
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
5816
6046
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
5817
6047
|
let matched = false;
|
|
5818
|
-
|
|
6048
|
+
logger12.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
5819
6049
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
5820
6050
|
mode,
|
|
5821
6051
|
onMutation: (context = {}) => {
|
|
@@ -5833,12 +6063,12 @@ ${text}`;
|
|
|
5833
6063
|
});
|
|
5834
6064
|
}
|
|
5835
6065
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
5836
|
-
|
|
6066
|
+
logger12.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
5837
6067
|
}
|
|
5838
6068
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
5839
6069
|
if (!candidate) return;
|
|
5840
6070
|
matched = true;
|
|
5841
|
-
|
|
6071
|
+
logger12.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
5842
6072
|
if (onMatch) {
|
|
5843
6073
|
onMatch({
|
|
5844
6074
|
link: candidate,
|
|
@@ -5854,7 +6084,7 @@ ${text}`;
|
|
|
5854
6084
|
return {
|
|
5855
6085
|
stop: async () => {
|
|
5856
6086
|
const result = await monitor.stop();
|
|
5857
|
-
|
|
6087
|
+
logger12.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
5858
6088
|
return result;
|
|
5859
6089
|
}
|
|
5860
6090
|
};
|
|
@@ -5894,8 +6124,8 @@ var Share = {
|
|
|
5894
6124
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
5895
6125
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
5896
6126
|
}
|
|
5897
|
-
|
|
5898
|
-
|
|
6127
|
+
logger12.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
6128
|
+
logger12.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
5899
6129
|
const stats = {
|
|
5900
6130
|
actionTimedOut: false,
|
|
5901
6131
|
domMutationCount: 0,
|
|
@@ -5920,7 +6150,7 @@ var Share = {
|
|
|
5920
6150
|
link: validated,
|
|
5921
6151
|
payloadText: String(payloadText || "")
|
|
5922
6152
|
};
|
|
5923
|
-
|
|
6153
|
+
logger12.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
5924
6154
|
return true;
|
|
5925
6155
|
};
|
|
5926
6156
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -5955,7 +6185,7 @@ var Share = {
|
|
|
5955
6185
|
try {
|
|
5956
6186
|
await monitor.stop();
|
|
5957
6187
|
} catch (error) {
|
|
5958
|
-
|
|
6188
|
+
logger12.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
5959
6189
|
}
|
|
5960
6190
|
};
|
|
5961
6191
|
const onResponse = async (response) => {
|
|
@@ -5968,29 +6198,29 @@ var Share = {
|
|
|
5968
6198
|
stats.responseSampleUrls.push(url);
|
|
5969
6199
|
}
|
|
5970
6200
|
if (stats.responseObserved <= 5) {
|
|
5971
|
-
|
|
6201
|
+
logger12.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
5972
6202
|
}
|
|
5973
6203
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
5974
6204
|
stats.responseMatched += 1;
|
|
5975
6205
|
stats.lastMatchedUrl = url;
|
|
5976
|
-
|
|
6206
|
+
logger12.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
5977
6207
|
const text = await response.text();
|
|
5978
6208
|
const hit = resolveResponseCandidate(text);
|
|
5979
6209
|
if (!hit?.link) {
|
|
5980
6210
|
if (stats.responseMatched <= 3) {
|
|
5981
|
-
|
|
6211
|
+
logger12.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
5982
6212
|
}
|
|
5983
6213
|
return;
|
|
5984
6214
|
}
|
|
5985
6215
|
stats.responseResolved += 1;
|
|
5986
|
-
|
|
6216
|
+
logger12.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
5987
6217
|
setCandidate("response", hit.link, hit.payloadText);
|
|
5988
6218
|
} catch (error) {
|
|
5989
|
-
|
|
6219
|
+
logger12.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
5990
6220
|
}
|
|
5991
6221
|
};
|
|
5992
6222
|
if (share.mode === "dom") {
|
|
5993
|
-
|
|
6223
|
+
logger12.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
5994
6224
|
domMonitor = await createDomShareMonitor(page, {
|
|
5995
6225
|
prefix: share.prefix,
|
|
5996
6226
|
selectors: domSelectors,
|
|
@@ -6005,14 +6235,14 @@ var Share = {
|
|
|
6005
6235
|
});
|
|
6006
6236
|
}
|
|
6007
6237
|
if (share.mode === "response") {
|
|
6008
|
-
|
|
6238
|
+
logger12.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
6009
6239
|
page.on("response", onResponse);
|
|
6010
6240
|
}
|
|
6011
6241
|
const deadline = Date.now() + timeoutMs;
|
|
6012
6242
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
6013
6243
|
try {
|
|
6014
6244
|
const actionTimeout = getRemainingMs();
|
|
6015
|
-
|
|
6245
|
+
logger12.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
6016
6246
|
if (actionTimeout > 0) {
|
|
6017
6247
|
let timer = null;
|
|
6018
6248
|
let actionError = null;
|
|
@@ -6026,21 +6256,21 @@ var Share = {
|
|
|
6026
6256
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
6027
6257
|
if (timer) clearTimeout(timer);
|
|
6028
6258
|
if (actionResult === "__ACTION_ERROR__") {
|
|
6029
|
-
|
|
6259
|
+
logger12.fail("captureLink.performActions", actionError);
|
|
6030
6260
|
throw actionError;
|
|
6031
6261
|
}
|
|
6032
6262
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
6033
6263
|
stats.actionTimedOut = true;
|
|
6034
|
-
|
|
6264
|
+
logger12.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
6035
6265
|
} else {
|
|
6036
|
-
|
|
6266
|
+
logger12.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
6037
6267
|
}
|
|
6038
6268
|
}
|
|
6039
6269
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
6040
6270
|
while (true) {
|
|
6041
6271
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
6042
6272
|
if (selected?.link) {
|
|
6043
|
-
|
|
6273
|
+
logger12.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
6044
6274
|
return {
|
|
6045
6275
|
link: selected.link,
|
|
6046
6276
|
payloadText: selected.payloadText,
|
|
@@ -6052,7 +6282,7 @@ var Share = {
|
|
|
6052
6282
|
if (remaining <= 0) break;
|
|
6053
6283
|
const now = Date.now();
|
|
6054
6284
|
if (now >= nextProgressLogTs) {
|
|
6055
|
-
|
|
6285
|
+
logger12.info(
|
|
6056
6286
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
6057
6287
|
);
|
|
6058
6288
|
nextProgressLogTs = now + 5e3;
|
|
@@ -6060,11 +6290,11 @@ var Share = {
|
|
|
6060
6290
|
await (0, import_delay2.default)(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
6061
6291
|
}
|
|
6062
6292
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
6063
|
-
|
|
6293
|
+
logger12.warning(
|
|
6064
6294
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
6065
6295
|
);
|
|
6066
6296
|
}
|
|
6067
|
-
|
|
6297
|
+
logger12.warning(
|
|
6068
6298
|
`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"}`
|
|
6069
6299
|
);
|
|
6070
6300
|
return {
|
|
@@ -6076,7 +6306,7 @@ var Share = {
|
|
|
6076
6306
|
} finally {
|
|
6077
6307
|
if (share.mode === "response") {
|
|
6078
6308
|
page.off("response", onResponse);
|
|
6079
|
-
|
|
6309
|
+
logger12.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
6080
6310
|
}
|
|
6081
6311
|
await stopDomMonitor();
|
|
6082
6312
|
}
|
|
@@ -6138,7 +6368,7 @@ var Share = {
|
|
|
6138
6368
|
...screenshotWatermarkify,
|
|
6139
6369
|
capturedAt
|
|
6140
6370
|
});
|
|
6141
|
-
const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta);
|
|
6371
|
+
const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
6142
6372
|
return buffer_.toString("base64");
|
|
6143
6373
|
} finally {
|
|
6144
6374
|
if (restore) {
|