@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/dist/index.js
CHANGED
|
@@ -323,18 +323,18 @@ var fallbackLog = {
|
|
|
323
323
|
error: (...args) => console.error(...args),
|
|
324
324
|
debug: (...args) => console.debug ? console.debug(...args) : console.log(...args)
|
|
325
325
|
};
|
|
326
|
-
var resolveLogMethod = (
|
|
327
|
-
if (
|
|
328
|
-
return
|
|
326
|
+
var resolveLogMethod = (logger13, name) => {
|
|
327
|
+
if (logger13 && typeof logger13[name] === "function") {
|
|
328
|
+
return logger13[name].bind(logger13);
|
|
329
329
|
}
|
|
330
|
-
if (name === "warning" &&
|
|
331
|
-
return
|
|
330
|
+
if (name === "warning" && logger13 && typeof logger13.warn === "function") {
|
|
331
|
+
return logger13.warn.bind(logger13);
|
|
332
332
|
}
|
|
333
333
|
return fallbackLog[name];
|
|
334
334
|
};
|
|
335
335
|
var defaultLogger = null;
|
|
336
|
-
var setDefaultLogger = (
|
|
337
|
-
defaultLogger =
|
|
336
|
+
var setDefaultLogger = (logger13) => {
|
|
337
|
+
defaultLogger = logger13;
|
|
338
338
|
};
|
|
339
339
|
var resolveLogger = (explicitLogger) => {
|
|
340
340
|
if (explicitLogger && typeof explicitLogger.info === "function") {
|
|
@@ -361,8 +361,8 @@ var colorize = (text, color) => {
|
|
|
361
361
|
var createBaseLogger = (prefix = "", explicitLogger) => {
|
|
362
362
|
const name = prefix ? String(prefix) : "";
|
|
363
363
|
const dispatch = (methodName, icon, message, color) => {
|
|
364
|
-
const
|
|
365
|
-
const logFn = resolveLogMethod(
|
|
364
|
+
const logger13 = resolveLogger(explicitLogger);
|
|
365
|
+
const logFn = resolveLogMethod(logger13, methodName);
|
|
366
366
|
const timestamp = colorize(`[${formatTimestamp()}]`, ANSI.gray);
|
|
367
367
|
const line = formatLine(name, icon, message);
|
|
368
368
|
const coloredLine = colorize(line, color);
|
|
@@ -4541,7 +4541,7 @@ var createTemplateLogger = (baseLogger = createBaseLogger()) => {
|
|
|
4541
4541
|
};
|
|
4542
4542
|
var getDefaultBaseLogger = () => createBaseLogger("");
|
|
4543
4543
|
var Logger = {
|
|
4544
|
-
setLogger: (
|
|
4544
|
+
setLogger: (logger13) => setDefaultLogger(logger13),
|
|
4545
4545
|
info: (message) => getDefaultBaseLogger().info(message),
|
|
4546
4546
|
success: (message) => getDefaultBaseLogger().success(message),
|
|
4547
4547
|
warning: (message) => getDefaultBaseLogger().warning(message),
|
|
@@ -4549,8 +4549,8 @@ var Logger = {
|
|
|
4549
4549
|
error: (message) => getDefaultBaseLogger().error(message),
|
|
4550
4550
|
debug: (message) => getDefaultBaseLogger().debug(message),
|
|
4551
4551
|
start: (message) => getDefaultBaseLogger().start(message),
|
|
4552
|
-
useTemplate: (
|
|
4553
|
-
if (
|
|
4552
|
+
useTemplate: (logger13) => {
|
|
4553
|
+
if (logger13) return createTemplateLogger(createBaseLogger("", logger13));
|
|
4554
4554
|
return createTemplateLogger();
|
|
4555
4555
|
}
|
|
4556
4556
|
};
|
|
@@ -4559,7 +4559,6 @@ var Logger = {
|
|
|
4559
4559
|
import delay2 from "delay";
|
|
4560
4560
|
|
|
4561
4561
|
// src/internals/watermarkify.js
|
|
4562
|
-
import sharp from "sharp";
|
|
4563
4562
|
var DEFAULT_TIMEZONE_OFFSET = 8;
|
|
4564
4563
|
var DEFAULT_RESOLVER_TIMEOUT_MS = 180;
|
|
4565
4564
|
var DEFAULT_IP_LOOKUP_TIMEOUT_MS = 1e4;
|
|
@@ -4568,7 +4567,7 @@ var DEFAULT_WATERMARK_ROTATE_DEG = -16;
|
|
|
4568
4567
|
var DEFAULT_WATERMARK_CELL_WIDTH = 860;
|
|
4569
4568
|
var DEFAULT_WATERMARK_CELL_HEIGHT = 330;
|
|
4570
4569
|
var DEFAULT_STRIP_LOGO_URL = "https://static.heartbitai.com/geo/icon/favicon.png";
|
|
4571
|
-
var DEFAULT_IP_LOOKUP_URL = "
|
|
4570
|
+
var DEFAULT_IP_LOOKUP_URL = "https://myip.ipip.net/json";
|
|
4572
4571
|
var DEFAULT_LOGO_FETCH_TIMEOUT_MS = 2500;
|
|
4573
4572
|
var DEFAULT_STRIP_ONE_LINE_HEIGHT = 78;
|
|
4574
4573
|
var DEFAULT_STRIP_WRAPPED_MIN_HEIGHT = 108;
|
|
@@ -4590,6 +4589,7 @@ var DEFAULT_STRIP_LINE_HEIGHT_RATIO = 1.28;
|
|
|
4590
4589
|
var DEFAULT_STRIP_PROMPT_MAX_LINES = 3;
|
|
4591
4590
|
var DEFAULT_STRIP_CONTENT_SAFE_PADDING_X = 12;
|
|
4592
4591
|
var DEFAULT_STRIP_TEXT_WIDTH_SAFETY = 10;
|
|
4592
|
+
var DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT = 1200;
|
|
4593
4593
|
var WEAK_LOCATION_VALUES = /* @__PURE__ */ new Set(["cn", "\u4E2D\u56FD"]);
|
|
4594
4594
|
var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
4595
4595
|
/(?:中国)?移动$/i,
|
|
@@ -4615,6 +4615,7 @@ var LOCATION_NETWORK_SUFFIX_PATTERNS = [
|
|
|
4615
4615
|
];
|
|
4616
4616
|
var cachedStripLogoSrcPromise = null;
|
|
4617
4617
|
var cachedEnrichmentByContext = /* @__PURE__ */ new WeakMap();
|
|
4618
|
+
var logger11 = createInternalLogger("Watermarkify");
|
|
4618
4619
|
var normalizeText = (value) => String(value || "").trim();
|
|
4619
4620
|
var toInline = (value, maxLen = 200) => {
|
|
4620
4621
|
const text = normalizeText(value);
|
|
@@ -4682,18 +4683,26 @@ var pickHeaderValue = async (response, names = []) => {
|
|
|
4682
4683
|
}
|
|
4683
4684
|
return "";
|
|
4684
4685
|
};
|
|
4685
|
-
var
|
|
4686
|
+
var parseIpIpJsonResponse = (rawText) => {
|
|
4686
4687
|
const text = normalizeWhitespace(rawText);
|
|
4687
|
-
if (!text)
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4688
|
+
if (!text || !text.startsWith("{") && !text.startsWith("[")) {
|
|
4689
|
+
return null;
|
|
4690
|
+
}
|
|
4691
|
+
try {
|
|
4692
|
+
const payload = JSON.parse(text);
|
|
4693
|
+
const ip = toInline(payload?.data?.ip || payload?.ip, 80);
|
|
4694
|
+
const locationParts = Array.isArray(payload?.data?.location) ? payload.data.location.map((item) => normalizeWhitespace(item)).filter(Boolean) : [];
|
|
4695
|
+
const location = toInline(
|
|
4696
|
+
stripLocationNetworkSuffix(locationParts.join(" ")),
|
|
4697
|
+
80
|
|
4698
|
+
);
|
|
4699
|
+
if (!ip && !location) {
|
|
4700
|
+
return null;
|
|
4701
|
+
}
|
|
4702
|
+
return { ip, location };
|
|
4703
|
+
} catch {
|
|
4694
4704
|
return null;
|
|
4695
4705
|
}
|
|
4696
|
-
return { ip, location };
|
|
4697
4706
|
};
|
|
4698
4707
|
var fillEnrichment = (target, source) => {
|
|
4699
4708
|
if (!target || !source || typeof source !== "object") {
|
|
@@ -4843,10 +4852,16 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
4843
4852
|
if (!resolved || typeof resolved !== "object") {
|
|
4844
4853
|
return null;
|
|
4845
4854
|
}
|
|
4846
|
-
|
|
4855
|
+
const enrichment = {
|
|
4847
4856
|
ip: toInline(resolved.ip, 80),
|
|
4848
4857
|
location: toInline(resolved.location, 80)
|
|
4849
4858
|
};
|
|
4859
|
+
if (enrichment.ip || enrichment.location) {
|
|
4860
|
+
logger11.info(`\u81EA\u5B9A\u4E49 resolver \u547D\u4E2D: ip=${enrichment.ip || "-"}, loc=${enrichment.location || "-"}`);
|
|
4861
|
+
} else {
|
|
4862
|
+
logger11.warning("\u81EA\u5B9A\u4E49 resolver \u5DF2\u6267\u884C\uFF0C\u4F46\u672A\u8FD4\u56DE IP/Loc");
|
|
4863
|
+
}
|
|
4864
|
+
return enrichment;
|
|
4850
4865
|
} finally {
|
|
4851
4866
|
controller?.abort();
|
|
4852
4867
|
}
|
|
@@ -4897,12 +4912,205 @@ var openProbePage = async (page) => {
|
|
|
4897
4912
|
}
|
|
4898
4913
|
return null;
|
|
4899
4914
|
};
|
|
4915
|
+
var readPngDimensions = (buffer) => {
|
|
4916
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 24) {
|
|
4917
|
+
return { width: 0, height: 0 };
|
|
4918
|
+
}
|
|
4919
|
+
const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
|
|
4920
|
+
for (let index = 0; index < pngSignature.length; index += 1) {
|
|
4921
|
+
if (buffer[index] !== pngSignature[index]) {
|
|
4922
|
+
return { width: 0, height: 0 };
|
|
4923
|
+
}
|
|
4924
|
+
}
|
|
4925
|
+
return {
|
|
4926
|
+
width: buffer.readUInt32BE(16),
|
|
4927
|
+
height: buffer.readUInt32BE(20)
|
|
4928
|
+
};
|
|
4929
|
+
};
|
|
4930
|
+
var readJpegDimensions = (buffer) => {
|
|
4931
|
+
if (!Buffer.isBuffer(buffer) || buffer.length < 4 || buffer[0] !== 255 || buffer[1] !== 216) {
|
|
4932
|
+
return { width: 0, height: 0 };
|
|
4933
|
+
}
|
|
4934
|
+
let offset = 2;
|
|
4935
|
+
while (offset + 9 <= buffer.length) {
|
|
4936
|
+
if (buffer[offset] !== 255) {
|
|
4937
|
+
offset += 1;
|
|
4938
|
+
continue;
|
|
4939
|
+
}
|
|
4940
|
+
const marker = buffer[offset + 1];
|
|
4941
|
+
offset += 2;
|
|
4942
|
+
if (marker === 216 || marker === 217) {
|
|
4943
|
+
continue;
|
|
4944
|
+
}
|
|
4945
|
+
if (marker === 218) {
|
|
4946
|
+
break;
|
|
4947
|
+
}
|
|
4948
|
+
if (offset + 2 > buffer.length) {
|
|
4949
|
+
break;
|
|
4950
|
+
}
|
|
4951
|
+
const segmentLength = buffer.readUInt16BE(offset);
|
|
4952
|
+
if (segmentLength < 2 || offset + segmentLength > buffer.length) {
|
|
4953
|
+
break;
|
|
4954
|
+
}
|
|
4955
|
+
const isStartOfFrame = marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204;
|
|
4956
|
+
if (isStartOfFrame && offset + 7 <= buffer.length) {
|
|
4957
|
+
return {
|
|
4958
|
+
height: buffer.readUInt16BE(offset + 3),
|
|
4959
|
+
width: buffer.readUInt16BE(offset + 5)
|
|
4960
|
+
};
|
|
4961
|
+
}
|
|
4962
|
+
offset += segmentLength;
|
|
4963
|
+
}
|
|
4964
|
+
return { width: 0, height: 0 };
|
|
4965
|
+
};
|
|
4966
|
+
var readImageInfo = (buffer) => {
|
|
4967
|
+
const png = readPngDimensions(buffer);
|
|
4968
|
+
if (png.width && png.height) {
|
|
4969
|
+
return {
|
|
4970
|
+
mimeType: "image/png",
|
|
4971
|
+
width: png.width,
|
|
4972
|
+
height: png.height
|
|
4973
|
+
};
|
|
4974
|
+
}
|
|
4975
|
+
const jpeg = readJpegDimensions(buffer);
|
|
4976
|
+
if (jpeg.width && jpeg.height) {
|
|
4977
|
+
return {
|
|
4978
|
+
mimeType: "image/jpeg",
|
|
4979
|
+
width: jpeg.width,
|
|
4980
|
+
height: jpeg.height
|
|
4981
|
+
};
|
|
4982
|
+
}
|
|
4983
|
+
return {
|
|
4984
|
+
mimeType: "",
|
|
4985
|
+
width: 0,
|
|
4986
|
+
height: 0
|
|
4987
|
+
};
|
|
4988
|
+
};
|
|
4989
|
+
var buildWatermarkifyRenderHtml = ({ imageSrc, overlaySvg, width, height }) => {
|
|
4990
|
+
const safeWidth = Math.max(1, Number(width) || 1);
|
|
4991
|
+
const safeHeight = Math.max(1, Number(height) || 1);
|
|
4992
|
+
return `
|
|
4993
|
+
<!doctype html>
|
|
4994
|
+
<html lang="zh-CN">
|
|
4995
|
+
<head>
|
|
4996
|
+
<meta charset="utf-8" />
|
|
4997
|
+
<style>
|
|
4998
|
+
html, body {
|
|
4999
|
+
margin: 0;
|
|
5000
|
+
padding: 0;
|
|
5001
|
+
width: ${safeWidth}px;
|
|
5002
|
+
height: ${safeHeight}px;
|
|
5003
|
+
overflow: hidden;
|
|
5004
|
+
background: #ffffff;
|
|
5005
|
+
}
|
|
5006
|
+
|
|
5007
|
+
body {
|
|
5008
|
+
position: relative;
|
|
5009
|
+
}
|
|
5010
|
+
|
|
5011
|
+
#pk-stage {
|
|
5012
|
+
position: relative;
|
|
5013
|
+
width: ${safeWidth}px;
|
|
5014
|
+
height: ${safeHeight}px;
|
|
5015
|
+
overflow: hidden;
|
|
5016
|
+
}
|
|
5017
|
+
|
|
5018
|
+
#pk-base-image {
|
|
5019
|
+
position: absolute;
|
|
5020
|
+
inset: 0;
|
|
5021
|
+
display: block;
|
|
5022
|
+
width: ${safeWidth}px;
|
|
5023
|
+
height: ${safeHeight}px;
|
|
5024
|
+
}
|
|
5025
|
+
|
|
5026
|
+
#pk-overlay {
|
|
5027
|
+
position: absolute;
|
|
5028
|
+
inset: 0;
|
|
5029
|
+
width: ${safeWidth}px;
|
|
5030
|
+
height: ${safeHeight}px;
|
|
5031
|
+
pointer-events: none;
|
|
5032
|
+
}
|
|
5033
|
+
</style>
|
|
5034
|
+
</head>
|
|
5035
|
+
<body>
|
|
5036
|
+
<div id="pk-stage">
|
|
5037
|
+
<img id="pk-base-image" src="${escapeHtmlAttribute(imageSrc)}" alt="" />
|
|
5038
|
+
<div id="pk-overlay">${overlaySvg}</div>
|
|
5039
|
+
</div>
|
|
5040
|
+
</body>
|
|
5041
|
+
</html>
|
|
5042
|
+
`;
|
|
5043
|
+
};
|
|
5044
|
+
var composeScreenshotBufferWithBrowser = async (page, buffer, overlaySvg, imageInfo = {}) => {
|
|
5045
|
+
if (!page || typeof page.context !== "function") {
|
|
5046
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u7F3A\u5C11\u53EF\u7528 page");
|
|
5047
|
+
return buffer;
|
|
5048
|
+
}
|
|
5049
|
+
const renderScope = await openProbePage(page);
|
|
5050
|
+
if (!renderScope?.page) {
|
|
5051
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA render page");
|
|
5052
|
+
return buffer;
|
|
5053
|
+
}
|
|
5054
|
+
try {
|
|
5055
|
+
const renderPage = renderScope.page;
|
|
5056
|
+
const safeWidth = Math.max(1, Number(imageInfo.width) || 1);
|
|
5057
|
+
const safeHeight = Math.max(1, Number(imageInfo.height) || 1);
|
|
5058
|
+
const viewportHeight = Math.max(
|
|
5059
|
+
1,
|
|
5060
|
+
Math.min(safeHeight, DEFAULT_BROWSER_COMPOSITOR_VIEWPORT_HEIGHT)
|
|
5061
|
+
);
|
|
5062
|
+
await renderPage.setViewportSize({
|
|
5063
|
+
width: safeWidth,
|
|
5064
|
+
height: viewportHeight
|
|
5065
|
+
}).catch(() => {
|
|
5066
|
+
});
|
|
5067
|
+
await renderPage.setContent(buildWatermarkifyRenderHtml({
|
|
5068
|
+
imageSrc: `data:${imageInfo.mimeType || "image/png"};base64,${buffer.toString("base64")}`,
|
|
5069
|
+
overlaySvg,
|
|
5070
|
+
width: safeWidth,
|
|
5071
|
+
height: safeHeight
|
|
5072
|
+
}), {
|
|
5073
|
+
waitUntil: "load"
|
|
5074
|
+
});
|
|
5075
|
+
await renderPage.waitForFunction(() => {
|
|
5076
|
+
const image = document.getElementById("pk-base-image");
|
|
5077
|
+
return image instanceof HTMLImageElement && image.complete && image.naturalWidth > 0 && image.naturalHeight > 0;
|
|
5078
|
+
}, {
|
|
5079
|
+
timeout: 5e3
|
|
5080
|
+
}).catch(() => {
|
|
5081
|
+
});
|
|
5082
|
+
await renderPage.evaluate(async () => {
|
|
5083
|
+
if (document.fonts?.ready) {
|
|
5084
|
+
await document.fonts.ready.catch(() => {
|
|
5085
|
+
});
|
|
5086
|
+
}
|
|
5087
|
+
}).catch(() => {
|
|
5088
|
+
});
|
|
5089
|
+
const composed = await renderPage.screenshot({
|
|
5090
|
+
type: "png",
|
|
5091
|
+
fullPage: true,
|
|
5092
|
+
animations: "disabled"
|
|
5093
|
+
}).catch((error) => {
|
|
5094
|
+
logger11.warning(`watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
5095
|
+
return null;
|
|
5096
|
+
});
|
|
5097
|
+
if (Buffer.isBuffer(composed) && composed.length > 0) {
|
|
5098
|
+
return composed;
|
|
5099
|
+
}
|
|
5100
|
+
logger11.warning("watermarkify \u6D4F\u89C8\u5668\u5408\u6210\u5931\u8D25: \u672A\u5F97\u5230\u6709\u6548\u622A\u56FE\u7ED3\u679C");
|
|
5101
|
+
return buffer;
|
|
5102
|
+
} finally {
|
|
5103
|
+
await renderScope.close().catch(() => {
|
|
5104
|
+
});
|
|
5105
|
+
}
|
|
5106
|
+
};
|
|
4900
5107
|
var resolveWithIpLookup = async (page, options = {}) => {
|
|
4901
5108
|
if (!page || typeof page.context !== "function" || options.ipLookup === false) {
|
|
4902
5109
|
return null;
|
|
4903
5110
|
}
|
|
4904
5111
|
const probeScope = await openProbePage(page);
|
|
4905
5112
|
if (!probeScope?.page) {
|
|
5113
|
+
logger11.warning("ipLookup \u8DF3\u8FC7: \u65E0\u6CD5\u521B\u5EFA probe page");
|
|
4906
5114
|
return null;
|
|
4907
5115
|
}
|
|
4908
5116
|
const timeoutMs = Math.max(
|
|
@@ -4911,10 +5119,16 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
4911
5119
|
);
|
|
4912
5120
|
try {
|
|
4913
5121
|
const probePage = probeScope.page;
|
|
5122
|
+
logger11.info(`ipLookup \u5C1D\u8BD5: url=${DEFAULT_IP_LOOKUP_URL}, timeoutMs=${timeoutMs}`);
|
|
4914
5123
|
const response = await probePage.goto(DEFAULT_IP_LOOKUP_URL, {
|
|
4915
5124
|
waitUntil: "commit",
|
|
4916
5125
|
timeout: timeoutMs
|
|
4917
|
-
}).catch(() =>
|
|
5126
|
+
}).catch((error) => {
|
|
5127
|
+
logger11.warning(`ipLookup \u8BF7\u6C42\u5931\u8D25: url=${DEFAULT_IP_LOOKUP_URL}, error=${error instanceof Error ? error.message : String(error)}`);
|
|
5128
|
+
return null;
|
|
5129
|
+
});
|
|
5130
|
+
const status = response && typeof response.status === "function" ? response.status() : 0;
|
|
5131
|
+
const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
|
|
4918
5132
|
let rawText = "";
|
|
4919
5133
|
if (response && typeof response.text === "function") {
|
|
4920
5134
|
rawText = String(await withTimeout(
|
|
@@ -4930,8 +5144,15 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
4930
5144
|
Math.min(timeoutMs, 500)
|
|
4931
5145
|
) || "");
|
|
4932
5146
|
}
|
|
4933
|
-
|
|
4934
|
-
|
|
5147
|
+
const parsed = parseIpIpJsonResponse(rawText);
|
|
5148
|
+
if (parsed?.ip || parsed?.location) {
|
|
5149
|
+
logger11.info(`ipLookup \u6210\u529F: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, ip=${parsed.ip || "-"}, loc=${parsed.location || "-"}`);
|
|
5150
|
+
return parsed;
|
|
5151
|
+
}
|
|
5152
|
+
logger11.warning(`ipLookup \u672A\u89E3\u6790\u51FA IP/Loc: url=${DEFAULT_IP_LOOKUP_URL}, status=${status || "-"}, contentType=${contentType || "-"}, preview=${shortenTail(rawText, 120) || "[empty]"}`);
|
|
5153
|
+
return null;
|
|
5154
|
+
} catch (error) {
|
|
5155
|
+
logger11.warning(`ipLookup \u6267\u884C\u5F02\u5E38\uFF0C\u672A\u83B7\u5F97 IP/Loc: ${error instanceof Error ? error.message : String(error)}`);
|
|
4935
5156
|
return null;
|
|
4936
5157
|
} finally {
|
|
4937
5158
|
await probeScope.close().catch(() => {
|
|
@@ -4945,7 +5166,11 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
4945
5166
|
ip: toInline(options.ip, 80),
|
|
4946
5167
|
location: toInline(options.location, 80)
|
|
4947
5168
|
};
|
|
5169
|
+
logger11.info(`enrichment \u5F00\u59CB: host=${baseMeta.hostname || "-"}, hasPresetIp=${Boolean(merged.ip)}, hasPresetLoc=${Boolean(merged.location)}, ipLookup=${options.ipLookup !== false}`);
|
|
4948
5170
|
if (!merged.ip || !merged.location) {
|
|
5171
|
+
if (cached?.ip || cached?.location) {
|
|
5172
|
+
logger11.info(`enrichment \u547D\u4E2D\u4E0A\u4E0B\u6587\u7F13\u5B58: ip=${cached.ip || "-"}, loc=${cached.location || "-"}`);
|
|
5173
|
+
}
|
|
4949
5174
|
fillEnrichment(merged, cached);
|
|
4950
5175
|
}
|
|
4951
5176
|
if (!merged.ip || !merged.location) {
|
|
@@ -4968,10 +5193,16 @@ var resolveEnrichment = async (page, baseMeta, options) => {
|
|
|
4968
5193
|
"x-geo-country"
|
|
4969
5194
|
]), 80);
|
|
4970
5195
|
if (!merged.location || isWeakLocationValue(merged.location) && headerLocation) {
|
|
5196
|
+
logger11.info(`enrichment \u4F7F\u7528\u54CD\u5E94\u5934\u8865\u5145 Loc: ${headerLocation || "-"}`);
|
|
4971
5197
|
merged.location = headerLocation || merged.location;
|
|
4972
5198
|
}
|
|
4973
5199
|
}
|
|
4974
5200
|
writeCachedEnrichment(page, merged);
|
|
5201
|
+
if (merged.ip || merged.location) {
|
|
5202
|
+
logger11.info(`enrichment \u5B8C\u6210: ip=${merged.ip || "-"}, loc=${merged.location || "-"}`);
|
|
5203
|
+
} else {
|
|
5204
|
+
logger11.warning("enrichment \u5B8C\u6210: \u672A\u83B7\u5F97 IP/Loc");
|
|
5205
|
+
}
|
|
4975
5206
|
return merged;
|
|
4976
5207
|
};
|
|
4977
5208
|
var buildWatermarkStamp = ({ prompt, captureTime, ip, location }) => {
|
|
@@ -5018,6 +5249,7 @@ var buildStripSegments = ({ prompt, captureTime, ip, location }) => {
|
|
|
5018
5249
|
];
|
|
5019
5250
|
};
|
|
5020
5251
|
var escapeXml = (value) => String(value || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5252
|
+
var escapeHtmlAttribute = (value) => String(value || "").replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
5021
5253
|
var estimateTextWidth = (value, fontSize = 16) => {
|
|
5022
5254
|
const text = String(value || "");
|
|
5023
5255
|
let width = 0;
|
|
@@ -5629,28 +5861,26 @@ var buildWatermarkifySvg = (meta, imageWidth, imageHeight) => {
|
|
|
5629
5861
|
</svg>
|
|
5630
5862
|
`;
|
|
5631
5863
|
};
|
|
5632
|
-
var watermarkifyScreenshotBuffer = async (buffer, meta) => {
|
|
5864
|
+
var watermarkifyScreenshotBuffer = async (buffer, meta, page = null) => {
|
|
5633
5865
|
const hasWatermark = meta?.watermark?.enabled !== false && normalizeText(meta?.watermarkText);
|
|
5634
5866
|
const hasStrip = meta?.strip?.enabled !== false && Array.isArray(meta?.stripSegments) && meta.stripSegments.length > 0;
|
|
5635
5867
|
if (!Buffer.isBuffer(buffer) || !meta || !hasWatermark && !hasStrip) {
|
|
5636
5868
|
return buffer;
|
|
5637
5869
|
}
|
|
5638
|
-
const
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
const height = Math.max(1, Number(metadata?.height) || 0);
|
|
5642
|
-
if (!width || !height) {
|
|
5870
|
+
const imageInfo = readImageInfo(buffer);
|
|
5871
|
+
if (!imageInfo.width || !imageInfo.height || !imageInfo.mimeType) {
|
|
5872
|
+
logger11.warning("watermarkify \u8DF3\u8FC7: \u65E0\u6CD5\u89E3\u6790\u622A\u56FE\u5C3A\u5BF8\u6216\u683C\u5F0F");
|
|
5643
5873
|
return buffer;
|
|
5644
5874
|
}
|
|
5645
|
-
const overlaySvg = buildWatermarkifySvg(meta, width, height);
|
|
5875
|
+
const overlaySvg = buildWatermarkifySvg(meta, imageInfo.width, imageInfo.height);
|
|
5646
5876
|
if (!overlaySvg) {
|
|
5647
5877
|
return buffer;
|
|
5648
5878
|
}
|
|
5649
|
-
return await
|
|
5879
|
+
return await composeScreenshotBufferWithBrowser(page, buffer, overlaySvg, imageInfo);
|
|
5650
5880
|
};
|
|
5651
5881
|
|
|
5652
5882
|
// src/share.js
|
|
5653
|
-
var
|
|
5883
|
+
var logger12 = createInternalLogger("Share");
|
|
5654
5884
|
var DEFAULT_TIMEOUT_MS2 = 50 * 1e3;
|
|
5655
5885
|
var DEFAULT_PAYLOAD_SNAPSHOT_MAX_LEN = 500;
|
|
5656
5886
|
var DEFAULT_POLL_INTERVAL_MS = 120;
|
|
@@ -5787,7 +6017,7 @@ var createDomShareMonitor = async (page, options = {}) => {
|
|
|
5787
6017
|
const onMatch = typeof options.onMatch === "function" ? options.onMatch : null;
|
|
5788
6018
|
const onTelemetry = typeof options.onTelemetry === "function" ? options.onTelemetry : null;
|
|
5789
6019
|
let matched = false;
|
|
5790
|
-
|
|
6020
|
+
logger12.info(`DOM \u76D1\u542C\u51C6\u5907\u6302\u8F7D: selectors=${toJsonInline(selectors, 120)}, mode=${mode}`);
|
|
5791
6021
|
const monitor = await Mutation.useMonitor(page, selectors, {
|
|
5792
6022
|
mode,
|
|
5793
6023
|
onMutation: (context = {}) => {
|
|
@@ -5805,12 +6035,12 @@ ${text}`;
|
|
|
5805
6035
|
});
|
|
5806
6036
|
}
|
|
5807
6037
|
if (mutationCount <= 5 || mutationCount % 50 === 0) {
|
|
5808
|
-
|
|
6038
|
+
logger12.info(`DOM \u53D8\u5316\u5DF2\u6355\u83B7: mutationCount=${mutationCount}, mutationNodes=${mutationNodes.length}`);
|
|
5809
6039
|
}
|
|
5810
6040
|
const [candidate] = Utils.parseLinks(rawDom, { prefix }) || [];
|
|
5811
6041
|
if (!candidate) return;
|
|
5812
6042
|
matched = true;
|
|
5813
|
-
|
|
6043
|
+
logger12.success("captureLink.domHit", `DOM \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: mutationCount=${mutationCount}, link=${candidate}`);
|
|
5814
6044
|
if (onMatch) {
|
|
5815
6045
|
onMatch({
|
|
5816
6046
|
link: candidate,
|
|
@@ -5826,7 +6056,7 @@ ${text}`;
|
|
|
5826
6056
|
return {
|
|
5827
6057
|
stop: async () => {
|
|
5828
6058
|
const result = await monitor.stop();
|
|
5829
|
-
|
|
6059
|
+
logger12.info(`DOM \u76D1\u542C\u5DF2\u505C\u6B62: totalMutations=${result?.totalMutations || 0}`);
|
|
5830
6060
|
return result;
|
|
5831
6061
|
}
|
|
5832
6062
|
};
|
|
@@ -5866,8 +6096,8 @@ var Share = {
|
|
|
5866
6096
|
if (share.mode === "response" && apiMatchers.length === 0) {
|
|
5867
6097
|
throw new Error("Share.captureLink requires share.xurl[0] api matcher when mode=response");
|
|
5868
6098
|
}
|
|
5869
|
-
|
|
5870
|
-
|
|
6099
|
+
logger12.start("captureLink", `mode=${share.mode}, timeoutMs=${timeoutMs}, prefix=${share.prefix}`);
|
|
6100
|
+
logger12.info(`captureLink \u914D\u7F6E: xurl=${toJsonInline(share.xurl)}, domMode=${domMode}, domSelectors=${toJsonInline(domSelectors, 120)}`);
|
|
5871
6101
|
const stats = {
|
|
5872
6102
|
actionTimedOut: false,
|
|
5873
6103
|
domMutationCount: 0,
|
|
@@ -5892,7 +6122,7 @@ var Share = {
|
|
|
5892
6122
|
link: validated,
|
|
5893
6123
|
payloadText: String(payloadText || "")
|
|
5894
6124
|
};
|
|
5895
|
-
|
|
6125
|
+
logger12.info(`\u5019\u9009\u94FE\u63A5\u5DF2\u786E\u8BA4: source=${source}, link=${validated}`);
|
|
5896
6126
|
return true;
|
|
5897
6127
|
};
|
|
5898
6128
|
const resolveResponseCandidate = (responseText) => {
|
|
@@ -5927,7 +6157,7 @@ var Share = {
|
|
|
5927
6157
|
try {
|
|
5928
6158
|
await monitor.stop();
|
|
5929
6159
|
} catch (error) {
|
|
5930
|
-
|
|
6160
|
+
logger12.warning(`\u505C\u6B62 DOM \u76D1\u542C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
|
|
5931
6161
|
}
|
|
5932
6162
|
};
|
|
5933
6163
|
const onResponse = async (response) => {
|
|
@@ -5940,29 +6170,29 @@ var Share = {
|
|
|
5940
6170
|
stats.responseSampleUrls.push(url);
|
|
5941
6171
|
}
|
|
5942
6172
|
if (stats.responseObserved <= 5) {
|
|
5943
|
-
|
|
6173
|
+
logger12.info(`\u63A5\u53E3\u54CD\u5E94\u91C7\u6837(${stats.responseObserved}): ${url}`);
|
|
5944
6174
|
}
|
|
5945
6175
|
if (!apiMatchers.some((matcher) => url.includes(matcher))) return;
|
|
5946
6176
|
stats.responseMatched += 1;
|
|
5947
6177
|
stats.lastMatchedUrl = url;
|
|
5948
|
-
|
|
6178
|
+
logger12.info(`\u63A5\u53E3\u547D\u4E2D\u5339\u914D(${stats.responseMatched}): ${url}`);
|
|
5949
6179
|
const text = await response.text();
|
|
5950
6180
|
const hit = resolveResponseCandidate(text);
|
|
5951
6181
|
if (!hit?.link) {
|
|
5952
6182
|
if (stats.responseMatched <= 3) {
|
|
5953
|
-
|
|
6183
|
+
logger12.info(`\u63A5\u53E3\u89E3\u6790\u5B8C\u6210\u4F46\u672A\u63D0\u53D6\u5230\u5206\u4EAB\u94FE\u63A5: payloadSize=${text.length}`);
|
|
5954
6184
|
}
|
|
5955
6185
|
return;
|
|
5956
6186
|
}
|
|
5957
6187
|
stats.responseResolved += 1;
|
|
5958
|
-
|
|
6188
|
+
logger12.success("captureLink.responseHit", `\u63A5\u53E3\u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: url=${url}, link=${hit.link}`);
|
|
5959
6189
|
setCandidate("response", hit.link, hit.payloadText);
|
|
5960
6190
|
} catch (error) {
|
|
5961
|
-
|
|
6191
|
+
logger12.warning(`\u63A5\u53E3\u54CD\u5E94\u5904\u7406\u5F02\u5E38: ${error instanceof Error ? error.message : String(error)}`);
|
|
5962
6192
|
}
|
|
5963
6193
|
};
|
|
5964
6194
|
if (share.mode === "dom") {
|
|
5965
|
-
|
|
6195
|
+
logger12.info("\u5F53\u524D\u4E3A DOM \u6A21\u5F0F\uFF0C\u4EC5\u542F\u7528 DOM \u76D1\u542C");
|
|
5966
6196
|
domMonitor = await createDomShareMonitor(page, {
|
|
5967
6197
|
prefix: share.prefix,
|
|
5968
6198
|
selectors: domSelectors,
|
|
@@ -5977,14 +6207,14 @@ var Share = {
|
|
|
5977
6207
|
});
|
|
5978
6208
|
}
|
|
5979
6209
|
if (share.mode === "response") {
|
|
5980
|
-
|
|
6210
|
+
logger12.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
|
|
5981
6211
|
page.on("response", onResponse);
|
|
5982
6212
|
}
|
|
5983
6213
|
const deadline = Date.now() + timeoutMs;
|
|
5984
6214
|
const getRemainingMs = () => Math.max(0, deadline - Date.now());
|
|
5985
6215
|
try {
|
|
5986
6216
|
const actionTimeout = getRemainingMs();
|
|
5987
|
-
|
|
6217
|
+
logger12.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
|
|
5988
6218
|
if (actionTimeout > 0) {
|
|
5989
6219
|
let timer = null;
|
|
5990
6220
|
let actionError = null;
|
|
@@ -5998,21 +6228,21 @@ var Share = {
|
|
|
5998
6228
|
const actionResult = await Promise.race([actionPromise, timeoutPromise]);
|
|
5999
6229
|
if (timer) clearTimeout(timer);
|
|
6000
6230
|
if (actionResult === "__ACTION_ERROR__") {
|
|
6001
|
-
|
|
6231
|
+
logger12.fail("captureLink.performActions", actionError);
|
|
6002
6232
|
throw actionError;
|
|
6003
6233
|
}
|
|
6004
6234
|
if (actionResult === "__ACTION_TIMEOUT__") {
|
|
6005
6235
|
stats.actionTimedOut = true;
|
|
6006
|
-
|
|
6236
|
+
logger12.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
|
|
6007
6237
|
} else {
|
|
6008
|
-
|
|
6238
|
+
logger12.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
|
|
6009
6239
|
}
|
|
6010
6240
|
}
|
|
6011
6241
|
let nextProgressLogTs = Date.now() + 3e3;
|
|
6012
6242
|
while (true) {
|
|
6013
6243
|
const selected = share.mode === "dom" ? candidates.dom : candidates.response;
|
|
6014
6244
|
if (selected?.link) {
|
|
6015
|
-
|
|
6245
|
+
logger12.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
|
|
6016
6246
|
return {
|
|
6017
6247
|
link: selected.link,
|
|
6018
6248
|
payloadText: selected.payloadText,
|
|
@@ -6024,7 +6254,7 @@ var Share = {
|
|
|
6024
6254
|
if (remaining <= 0) break;
|
|
6025
6255
|
const now = Date.now();
|
|
6026
6256
|
if (now >= nextProgressLogTs) {
|
|
6027
|
-
|
|
6257
|
+
logger12.info(
|
|
6028
6258
|
`captureLink \u7B49\u5F85\u4E2D: remaining=${remaining}ms, domMutationCount=${stats.domMutationCount}, responseMatched=${stats.responseMatched}`
|
|
6029
6259
|
);
|
|
6030
6260
|
nextProgressLogTs = now + 5e3;
|
|
@@ -6032,11 +6262,11 @@ var Share = {
|
|
|
6032
6262
|
await delay2(Math.max(0, Math.min(DEFAULT_POLL_INTERVAL_MS, remaining)));
|
|
6033
6263
|
}
|
|
6034
6264
|
if (share.mode === "response" && stats.responseMatched === 0) {
|
|
6035
|
-
|
|
6265
|
+
logger12.warning(
|
|
6036
6266
|
`\u63A5\u53E3\u76D1\u542C\u672A\u547D\u4E2D: apiMatchers=${toJsonInline(apiMatchers, 220)}, \u54CD\u5E94\u6837\u672CURLs=${toJsonInline(stats.responseSampleUrls, 420)}`
|
|
6037
6267
|
);
|
|
6038
6268
|
}
|
|
6039
|
-
|
|
6269
|
+
logger12.warning(
|
|
6040
6270
|
`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"}`
|
|
6041
6271
|
);
|
|
6042
6272
|
return {
|
|
@@ -6048,7 +6278,7 @@ var Share = {
|
|
|
6048
6278
|
} finally {
|
|
6049
6279
|
if (share.mode === "response") {
|
|
6050
6280
|
page.off("response", onResponse);
|
|
6051
|
-
|
|
6281
|
+
logger12.info("response \u76D1\u542C\u5DF2\u5378\u8F7D");
|
|
6052
6282
|
}
|
|
6053
6283
|
await stopDomMonitor();
|
|
6054
6284
|
}
|
|
@@ -6110,7 +6340,7 @@ var Share = {
|
|
|
6110
6340
|
...screenshotWatermarkify,
|
|
6111
6341
|
capturedAt
|
|
6112
6342
|
});
|
|
6113
|
-
const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta);
|
|
6343
|
+
const buffer_ = await watermarkifyScreenshotBuffer(rawBuffer, watermarkifyMeta, page);
|
|
6114
6344
|
return buffer_.toString("base64");
|
|
6115
6345
|
} finally {
|
|
6116
6346
|
if (restore) {
|