@skrillex1224/playwright-toolkit 3.0.8 → 3.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +12 -0
- package/dist/index.cjs +35 -3
- package/dist/index.js +36 -4
- package/dist/internals/proxy-meter.js +51 -5
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -2853,6 +2853,7 @@ var createActorInfo = (info) => {
|
|
|
2853
2853
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path2 }) => {
|
|
2854
2854
|
const safeProtocol = String(protocol2).trim();
|
|
2855
2855
|
const safeDomain = normalizeDomain(domain2);
|
|
2856
|
+
if (!safeDomain) return "";
|
|
2856
2857
|
const safePath = normalizePath(path2);
|
|
2857
2858
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
2858
2859
|
};
|
|
@@ -3060,6 +3061,17 @@ var ActorInfo = {
|
|
|
3060
3061
|
prefix: "",
|
|
3061
3062
|
xurl: []
|
|
3062
3063
|
}
|
|
3064
|
+
}),
|
|
3065
|
+
webpage: createActorInfo({
|
|
3066
|
+
key: "webpage",
|
|
3067
|
+
name: "\u901A\u7528\u7F51\u9875",
|
|
3068
|
+
domain: "",
|
|
3069
|
+
path: "/",
|
|
3070
|
+
share: {
|
|
3071
|
+
mode: "dom",
|
|
3072
|
+
prefix: "",
|
|
3073
|
+
xurl: []
|
|
3074
|
+
}
|
|
3063
3075
|
})
|
|
3064
3076
|
};
|
|
3065
3077
|
|
package/dist/index.cjs
CHANGED
|
@@ -149,6 +149,7 @@ var createActorInfo = (info) => {
|
|
|
149
149
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
150
150
|
const safeProtocol = String(protocol2).trim();
|
|
151
151
|
const safeDomain = normalizeDomain(domain2);
|
|
152
|
+
if (!safeDomain) return "";
|
|
152
153
|
const safePath = normalizePath(path4);
|
|
153
154
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
154
155
|
};
|
|
@@ -356,6 +357,17 @@ var ActorInfo = {
|
|
|
356
357
|
prefix: "",
|
|
357
358
|
xurl: []
|
|
358
359
|
}
|
|
360
|
+
}),
|
|
361
|
+
webpage: createActorInfo({
|
|
362
|
+
key: "webpage",
|
|
363
|
+
name: "\u901A\u7528\u7F51\u9875",
|
|
364
|
+
domain: "",
|
|
365
|
+
path: "/",
|
|
366
|
+
share: {
|
|
367
|
+
mode: "dom",
|
|
368
|
+
prefix: "",
|
|
369
|
+
xurl: []
|
|
370
|
+
}
|
|
359
371
|
})
|
|
360
372
|
};
|
|
361
373
|
|
|
@@ -1196,6 +1208,18 @@ var ensureLogPath = () => {
|
|
|
1196
1208
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
1197
1209
|
return import_path.default.join(baseDir, label);
|
|
1198
1210
|
};
|
|
1211
|
+
var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
|
|
1212
|
+
var writeChildOutput = (stream, output, prefix) => {
|
|
1213
|
+
if (!stream || !output) return;
|
|
1214
|
+
output.on("data", (chunk) => {
|
|
1215
|
+
const text = chunk?.toString?.() || String(chunk || "");
|
|
1216
|
+
if (!text) return;
|
|
1217
|
+
for (const line of text.split(/\r?\n/)) {
|
|
1218
|
+
if (!line) continue;
|
|
1219
|
+
stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
};
|
|
1199
1223
|
var readSnapshot = (logPath) => {
|
|
1200
1224
|
if (!logPath || !(0, import_fs.existsSync)(logPath)) return null;
|
|
1201
1225
|
try {
|
|
@@ -1363,6 +1387,7 @@ var startProxyMeter = (options = {}) => {
|
|
|
1363
1387
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
1364
1388
|
const port = pickFreePort();
|
|
1365
1389
|
const logPath = ensureLogPath();
|
|
1390
|
+
const stdioLogPath = ensureStdioLogPath(logPath);
|
|
1366
1391
|
const scriptPath = resolveScriptPath();
|
|
1367
1392
|
const debugMode = Boolean(options.debugMode);
|
|
1368
1393
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -1375,19 +1400,26 @@ var startProxyMeter = (options = {}) => {
|
|
|
1375
1400
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
1376
1401
|
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
1377
1402
|
};
|
|
1403
|
+
const stdioLog = (0, import_fs.createWriteStream)(stdioLogPath, { flags: "a" });
|
|
1404
|
+
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
|
|
1378
1405
|
const child = (0, import_child_process.spawn)(process.execPath, [scriptPath], {
|
|
1379
1406
|
env,
|
|
1380
|
-
stdio: ["ignore", "
|
|
1407
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1381
1408
|
});
|
|
1382
|
-
child.
|
|
1409
|
+
writeChildOutput(stdioLog, child.stdout, "stdout");
|
|
1410
|
+
writeChildOutput(stdioLog, child.stderr, "stderr");
|
|
1411
|
+
child.once("exit", (code, signal) => {
|
|
1412
|
+
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
|
|
1413
|
+
stdioLog.end();
|
|
1383
1414
|
if (code && code !== 0) {
|
|
1384
|
-
logger2.warn(`[proxy-meter] exited with code ${code}`);
|
|
1415
|
+
logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
|
|
1385
1416
|
}
|
|
1386
1417
|
});
|
|
1387
1418
|
runtime = {
|
|
1388
1419
|
proc: child,
|
|
1389
1420
|
port,
|
|
1390
1421
|
logPath,
|
|
1422
|
+
stdioLogPath,
|
|
1391
1423
|
startedAt: Date.now()
|
|
1392
1424
|
};
|
|
1393
1425
|
registerCleanup();
|
package/dist/index.js
CHANGED
|
@@ -122,6 +122,7 @@ var createActorInfo = (info) => {
|
|
|
122
122
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
123
123
|
const safeProtocol = String(protocol2).trim();
|
|
124
124
|
const safeDomain = normalizeDomain(domain2);
|
|
125
|
+
if (!safeDomain) return "";
|
|
125
126
|
const safePath = normalizePath(path4);
|
|
126
127
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
127
128
|
};
|
|
@@ -329,6 +330,17 @@ var ActorInfo = {
|
|
|
329
330
|
prefix: "",
|
|
330
331
|
xurl: []
|
|
331
332
|
}
|
|
333
|
+
}),
|
|
334
|
+
webpage: createActorInfo({
|
|
335
|
+
key: "webpage",
|
|
336
|
+
name: "\u901A\u7528\u7F51\u9875",
|
|
337
|
+
domain: "",
|
|
338
|
+
path: "/",
|
|
339
|
+
share: {
|
|
340
|
+
mode: "dom",
|
|
341
|
+
prefix: "",
|
|
342
|
+
xurl: []
|
|
343
|
+
}
|
|
332
344
|
})
|
|
333
345
|
};
|
|
334
346
|
|
|
@@ -1059,7 +1071,7 @@ import { serializeError as serializeError2 } from "serialize-error";
|
|
|
1059
1071
|
|
|
1060
1072
|
// src/internals/proxy-meter-runtime.js
|
|
1061
1073
|
import { spawn, spawnSync } from "child_process";
|
|
1062
|
-
import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
1074
|
+
import { createWriteStream, existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
1063
1075
|
import { tmpdir } from "os";
|
|
1064
1076
|
import path from "path";
|
|
1065
1077
|
import { fileURLToPath } from "url";
|
|
@@ -1168,6 +1180,18 @@ var ensureLogPath = () => {
|
|
|
1168
1180
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
1169
1181
|
return path.join(baseDir, label);
|
|
1170
1182
|
};
|
|
1183
|
+
var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
|
|
1184
|
+
var writeChildOutput = (stream, output, prefix) => {
|
|
1185
|
+
if (!stream || !output) return;
|
|
1186
|
+
output.on("data", (chunk) => {
|
|
1187
|
+
const text = chunk?.toString?.() || String(chunk || "");
|
|
1188
|
+
if (!text) return;
|
|
1189
|
+
for (const line of text.split(/\r?\n/)) {
|
|
1190
|
+
if (!line) continue;
|
|
1191
|
+
stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
|
|
1192
|
+
}
|
|
1193
|
+
});
|
|
1194
|
+
};
|
|
1171
1195
|
var readSnapshot = (logPath) => {
|
|
1172
1196
|
if (!logPath || !existsSync(logPath)) return null;
|
|
1173
1197
|
try {
|
|
@@ -1335,6 +1359,7 @@ var startProxyMeter = (options = {}) => {
|
|
|
1335
1359
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
1336
1360
|
const port = pickFreePort();
|
|
1337
1361
|
const logPath = ensureLogPath();
|
|
1362
|
+
const stdioLogPath = ensureStdioLogPath(logPath);
|
|
1338
1363
|
const scriptPath = resolveScriptPath();
|
|
1339
1364
|
const debugMode = Boolean(options.debugMode);
|
|
1340
1365
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -1347,19 +1372,26 @@ var startProxyMeter = (options = {}) => {
|
|
|
1347
1372
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
1348
1373
|
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
1349
1374
|
};
|
|
1375
|
+
const stdioLog = createWriteStream(stdioLogPath, { flags: "a" });
|
|
1376
|
+
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
|
|
1350
1377
|
const child = spawn(process.execPath, [scriptPath], {
|
|
1351
1378
|
env,
|
|
1352
|
-
stdio: ["ignore", "
|
|
1379
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1353
1380
|
});
|
|
1354
|
-
child.
|
|
1381
|
+
writeChildOutput(stdioLog, child.stdout, "stdout");
|
|
1382
|
+
writeChildOutput(stdioLog, child.stderr, "stderr");
|
|
1383
|
+
child.once("exit", (code, signal) => {
|
|
1384
|
+
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
|
|
1385
|
+
stdioLog.end();
|
|
1355
1386
|
if (code && code !== 0) {
|
|
1356
|
-
logger2.warn(`[proxy-meter] exited with code ${code}`);
|
|
1387
|
+
logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
|
|
1357
1388
|
}
|
|
1358
1389
|
});
|
|
1359
1390
|
runtime = {
|
|
1360
1391
|
proc: child,
|
|
1361
1392
|
port,
|
|
1362
1393
|
logPath,
|
|
1394
|
+
stdioLogPath,
|
|
1363
1395
|
startedAt: Date.now()
|
|
1364
1396
|
};
|
|
1365
1397
|
registerCleanup();
|
|
@@ -32,6 +32,25 @@ const state = {
|
|
|
32
32
|
: null,
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
+
const formatFatalError = (error) => {
|
|
36
|
+
if (error instanceof Error) {
|
|
37
|
+
return error.stack || error.message || String(error);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return JSON.stringify(error);
|
|
41
|
+
} catch {
|
|
42
|
+
return String(error);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const exitAfterFatal = (kind, error) => {
|
|
47
|
+
try {
|
|
48
|
+
console.error(`[proxy-meter] fatal ${kind}: ${formatFatalError(error)}`);
|
|
49
|
+
} catch {}
|
|
50
|
+
flushSnapshot();
|
|
51
|
+
process.exit(1);
|
|
52
|
+
};
|
|
53
|
+
|
|
35
54
|
const getHostBucket = (host) => {
|
|
36
55
|
if (!host) return null;
|
|
37
56
|
if (!state.hosts[host]) {
|
|
@@ -60,6 +79,21 @@ const safeError = (error) => {
|
|
|
60
79
|
return message.length > 240 ? message.slice(0, 240) : message;
|
|
61
80
|
};
|
|
62
81
|
|
|
82
|
+
const sendBadGateway = (res, error = null) => {
|
|
83
|
+
if (!res || res.destroyed || res.writableEnded) return;
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
if (!res.headersSent) {
|
|
87
|
+
res.writeHead(502);
|
|
88
|
+
res.end('Bad Gateway');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Headers are already committed; the only truthful error signal left is closing the stream.
|
|
93
|
+
res.destroy(error instanceof Error ? error : undefined);
|
|
94
|
+
} catch {}
|
|
95
|
+
};
|
|
96
|
+
|
|
63
97
|
const statusLabel = (statusCode, error) => {
|
|
64
98
|
const code = Number(statusCode) || 0;
|
|
65
99
|
if (error || code <= 0) return 'ERR';
|
|
@@ -349,8 +383,7 @@ const forwardHttp = (req, res) => {
|
|
|
349
383
|
|
|
350
384
|
if (!target) {
|
|
351
385
|
tracker.close({ statusCode: 0, error: 'invalid_target_url' });
|
|
352
|
-
res
|
|
353
|
-
res.end('Bad Gateway');
|
|
386
|
+
sendBadGateway(res);
|
|
354
387
|
return;
|
|
355
388
|
}
|
|
356
389
|
|
|
@@ -381,7 +414,19 @@ const forwardHttp = (req, res) => {
|
|
|
381
414
|
let responseStatus = 0;
|
|
382
415
|
const proxyReq = http.request(requestOptions, (proxyRes) => {
|
|
383
416
|
responseStatus = Number(proxyRes.statusCode) || 0;
|
|
384
|
-
res.
|
|
417
|
+
if (res.destroyed || res.writableEnded) {
|
|
418
|
+
tracker.close({ statusCode: responseStatus || 499, error: 'client_response_closed' });
|
|
419
|
+
proxyRes.resume();
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
try {
|
|
423
|
+
res.writeHead(responseStatus || 502, proxyRes.headers);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
tracker.close({ statusCode: responseStatus, error: safeError(error) });
|
|
426
|
+
proxyRes.resume();
|
|
427
|
+
sendBadGateway(res, error);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
385
430
|
proxyRes.on('data', (chunk) => {
|
|
386
431
|
const size = chunk?.length || 0;
|
|
387
432
|
addTraffic(hostname, 'in', size);
|
|
@@ -412,8 +457,7 @@ const forwardHttp = (req, res) => {
|
|
|
412
457
|
|
|
413
458
|
proxyReq.on('error', (error) => {
|
|
414
459
|
tracker.close({ statusCode: responseStatus, error: safeError(error) });
|
|
415
|
-
res
|
|
416
|
-
res.end('Bad Gateway');
|
|
460
|
+
sendBadGateway(res, error);
|
|
417
461
|
});
|
|
418
462
|
};
|
|
419
463
|
|
|
@@ -545,5 +589,7 @@ const shutdown = () => {
|
|
|
545
589
|
process.exit(0);
|
|
546
590
|
};
|
|
547
591
|
|
|
592
|
+
process.on('uncaughtException', (error) => exitAfterFatal('uncaughtException', error));
|
|
593
|
+
process.on('unhandledRejection', (error) => exitAfterFatal('unhandledRejection', error));
|
|
548
594
|
process.on('SIGINT', shutdown);
|
|
549
595
|
process.on('SIGTERM', shutdown);
|