@crouton-kit/capture 1.4.0 → 1.4.1
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/bin/capture +53 -32
- package/package.json +1 -1
- package/src/cdp/detect.ts +61 -20
package/bin/capture
CHANGED
|
@@ -2232,7 +2232,7 @@ var require_websocket = __commonJS({
|
|
|
2232
2232
|
"use strict";
|
|
2233
2233
|
var EventEmitter = require("events");
|
|
2234
2234
|
var https = require("https");
|
|
2235
|
-
var
|
|
2235
|
+
var http2 = require("http");
|
|
2236
2236
|
var net5 = require("net");
|
|
2237
2237
|
var tls = require("tls");
|
|
2238
2238
|
var { randomBytes: randomBytes10, createHash: createHash5 } = require("crypto");
|
|
@@ -2766,7 +2766,7 @@ var require_websocket = __commonJS({
|
|
|
2766
2766
|
}
|
|
2767
2767
|
const defaultPort = isSecure ? 443 : 80;
|
|
2768
2768
|
const key = randomBytes10(16).toString("base64");
|
|
2769
|
-
const request = isSecure ? https.request :
|
|
2769
|
+
const request = isSecure ? https.request : http2.request;
|
|
2770
2770
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
2771
2771
|
let perMessageDeflate;
|
|
2772
2772
|
opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
|
|
@@ -3260,7 +3260,7 @@ var require_websocket_server = __commonJS({
|
|
|
3260
3260
|
"node_modules/.pnpm/ws@8.20.0/node_modules/ws/lib/websocket-server.js"(exports2, module2) {
|
|
3261
3261
|
"use strict";
|
|
3262
3262
|
var EventEmitter = require("events");
|
|
3263
|
-
var
|
|
3263
|
+
var http2 = require("http");
|
|
3264
3264
|
var { Duplex } = require("stream");
|
|
3265
3265
|
var { createHash: createHash5 } = require("crypto");
|
|
3266
3266
|
var extension2 = require_extension();
|
|
@@ -3335,8 +3335,8 @@ var require_websocket_server = __commonJS({
|
|
|
3335
3335
|
);
|
|
3336
3336
|
}
|
|
3337
3337
|
if (options.port != null) {
|
|
3338
|
-
this._server =
|
|
3339
|
-
const body =
|
|
3338
|
+
this._server = http2.createServer((req, res) => {
|
|
3339
|
+
const body = http2.STATUS_CODES[426];
|
|
3340
3340
|
res.writeHead(426, {
|
|
3341
3341
|
"Content-Length": body.length,
|
|
3342
3342
|
"Content-Type": "text/plain"
|
|
@@ -3623,7 +3623,7 @@ var require_websocket_server = __commonJS({
|
|
|
3623
3623
|
this.destroy();
|
|
3624
3624
|
}
|
|
3625
3625
|
function abortHandshake(socket, code, message, headers2) {
|
|
3626
|
-
message = message ||
|
|
3626
|
+
message = message || http2.STATUS_CODES[code];
|
|
3627
3627
|
headers2 = {
|
|
3628
3628
|
Connection: "close",
|
|
3629
3629
|
"Content-Type": "text/html",
|
|
@@ -3632,7 +3632,7 @@ var require_websocket_server = __commonJS({
|
|
|
3632
3632
|
};
|
|
3633
3633
|
socket.once("finish", socket.destroy);
|
|
3634
3634
|
socket.end(
|
|
3635
|
-
`HTTP/1.1 ${code} ${
|
|
3635
|
+
`HTTP/1.1 ${code} ${http2.STATUS_CODES[code]}\r
|
|
3636
3636
|
` + Object.keys(headers2).map((h) => `${h}: ${headers2[h]}`).join("\r\n") + "\r\n\r\n" + message
|
|
3637
3637
|
);
|
|
3638
3638
|
}
|
|
@@ -3779,6 +3779,39 @@ __export(detect_exports, {
|
|
|
3779
3779
|
identifyBrowserBundleId: () => identifyBrowserBundleId,
|
|
3780
3780
|
pickPreferredEndpoint: () => pickPreferredEndpoint
|
|
3781
3781
|
});
|
|
3782
|
+
function httpGetJson(port, path33, timeoutMs) {
|
|
3783
|
+
return new Promise((resolve12) => {
|
|
3784
|
+
const req = http.get(
|
|
3785
|
+
{ host: "localhost", port, path: path33, timeout: timeoutMs },
|
|
3786
|
+
(res) => {
|
|
3787
|
+
const status = res.statusCode ?? 0;
|
|
3788
|
+
if (status < 200 || status >= 300) {
|
|
3789
|
+
res.resume();
|
|
3790
|
+
resolve12(null);
|
|
3791
|
+
return;
|
|
3792
|
+
}
|
|
3793
|
+
let body = "";
|
|
3794
|
+
res.setEncoding("utf-8");
|
|
3795
|
+
res.on("data", (chunk) => {
|
|
3796
|
+
body += chunk;
|
|
3797
|
+
});
|
|
3798
|
+
res.on("end", () => {
|
|
3799
|
+
try {
|
|
3800
|
+
resolve12(JSON.parse(body));
|
|
3801
|
+
} catch {
|
|
3802
|
+
resolve12(null);
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
res.on("error", () => resolve12(null));
|
|
3806
|
+
}
|
|
3807
|
+
);
|
|
3808
|
+
req.on("timeout", () => {
|
|
3809
|
+
req.destroy();
|
|
3810
|
+
resolve12(null);
|
|
3811
|
+
});
|
|
3812
|
+
req.on("error", () => resolve12(null));
|
|
3813
|
+
});
|
|
3814
|
+
}
|
|
3782
3815
|
function getDefaultBrowserId() {
|
|
3783
3816
|
try {
|
|
3784
3817
|
const output = (0, import_child_process.execSync)(
|
|
@@ -3795,14 +3828,8 @@ function getDefaultBrowserId() {
|
|
|
3795
3828
|
}
|
|
3796
3829
|
async function probeCdpPort(port) {
|
|
3797
3830
|
try {
|
|
3798
|
-
const
|
|
3799
|
-
|
|
3800
|
-
const resp = await fetch(`http://localhost:${port}/json/version`, {
|
|
3801
|
-
signal: controller.signal
|
|
3802
|
-
});
|
|
3803
|
-
clearTimeout(timeout);
|
|
3804
|
-
if (resp.ok) {
|
|
3805
|
-
const version = await resp.json();
|
|
3831
|
+
const version = await httpGetJson(port, "/json/version", 500);
|
|
3832
|
+
if (version) {
|
|
3806
3833
|
const browser = version.Browser;
|
|
3807
3834
|
const userAgent = version["User-Agent"] ?? "";
|
|
3808
3835
|
if (!browser) return null;
|
|
@@ -3824,14 +3851,7 @@ async function probeCdpPort(port) {
|
|
|
3824
3851
|
}
|
|
3825
3852
|
async function probeHasPageTarget(port) {
|
|
3826
3853
|
try {
|
|
3827
|
-
const
|
|
3828
|
-
const timeout = setTimeout(() => controller.abort(), 500);
|
|
3829
|
-
const resp = await fetch(`http://localhost:${port}/json/list`, {
|
|
3830
|
-
signal: controller.signal
|
|
3831
|
-
});
|
|
3832
|
-
clearTimeout(timeout);
|
|
3833
|
-
if (!resp.ok) return false;
|
|
3834
|
-
const list2 = await resp.json();
|
|
3854
|
+
const list2 = await httpGetJson(port, "/json/list", 500);
|
|
3835
3855
|
return Array.isArray(list2) && list2.some((t) => t.type === "page");
|
|
3836
3856
|
} catch {
|
|
3837
3857
|
return false;
|
|
@@ -3926,10 +3946,11 @@ async function detectCdpPort() {
|
|
|
3926
3946
|
}
|
|
3927
3947
|
return pickPreferredEndpoint(endpoints, getDefaultBrowserId()).port;
|
|
3928
3948
|
}
|
|
3929
|
-
var import_child_process, BROWSER_PATTERNS;
|
|
3949
|
+
var import_child_process, http, BROWSER_PATTERNS;
|
|
3930
3950
|
var init_detect = __esm({
|
|
3931
3951
|
"src/cdp/detect.ts"() {
|
|
3932
3952
|
import_child_process = require("child_process");
|
|
3953
|
+
http = __toESM(require("http"));
|
|
3933
3954
|
BROWSER_PATTERNS = {
|
|
3934
3955
|
"company.thebrowser.browser": ["arc"],
|
|
3935
3956
|
"com.google.chrome": ["chrome", "google chrome"],
|
|
@@ -10295,7 +10316,7 @@ function validateHarAppendBatch(value, source) {
|
|
|
10295
10316
|
return { entries, incompleteLifecycles };
|
|
10296
10317
|
}
|
|
10297
10318
|
function captureVersion() {
|
|
10298
|
-
const version = "1.4.
|
|
10319
|
+
const version = "1.4.1";
|
|
10299
10320
|
return typeof version === "string" && version.length > 0 ? version : "development";
|
|
10300
10321
|
}
|
|
10301
10322
|
function token() {
|
|
@@ -12086,7 +12107,7 @@ function wallTime(value) {
|
|
|
12086
12107
|
}
|
|
12087
12108
|
}
|
|
12088
12109
|
function captureVersion2() {
|
|
12089
|
-
const version = "1.4.
|
|
12110
|
+
const version = "1.4.1";
|
|
12090
12111
|
return typeof version === "string" && version.length > 0 ? version : "development";
|
|
12091
12112
|
}
|
|
12092
12113
|
function deepFreeze(value) {
|
|
@@ -64688,8 +64709,8 @@ ${lanes.join("\n")}
|
|
|
64688
64709
|
}
|
|
64689
64710
|
function createPerModuleNameCache() {
|
|
64690
64711
|
const directoryPathMap = /* @__PURE__ */ new Map();
|
|
64691
|
-
return { get, set };
|
|
64692
|
-
function
|
|
64712
|
+
return { get: get2, set };
|
|
64713
|
+
function get2(directory) {
|
|
64693
64714
|
return directoryPathMap.get(toPath(directory, currentDirectory, getCanonicalFileName));
|
|
64694
64715
|
}
|
|
64695
64716
|
function set(directory, result) {
|
|
@@ -168021,12 +168042,12 @@ ${lanes.join("\n")}
|
|
|
168021
168042
|
...info,
|
|
168022
168043
|
parseable: !!content,
|
|
168023
168044
|
fileName,
|
|
168024
|
-
get,
|
|
168045
|
+
get: get2,
|
|
168025
168046
|
has(dependencyName, inGroups) {
|
|
168026
|
-
return !!
|
|
168047
|
+
return !!get2(dependencyName, inGroups);
|
|
168027
168048
|
}
|
|
168028
168049
|
};
|
|
168029
|
-
function
|
|
168050
|
+
function get2(dependencyName, inGroups = 15) {
|
|
168030
168051
|
for (const [group2, deps7] of dependencyGroups) {
|
|
168031
168052
|
if (deps7 && inGroups & group2) {
|
|
168032
168053
|
const dep = deps7.get(dependencyName);
|
|
@@ -243312,7 +243333,7 @@ precedence: explicit flag > active session > env. \`session start\` adopts only
|
|
|
243312
243333
|
explicit --target.`;
|
|
243313
243334
|
}
|
|
243314
243335
|
function printVersion() {
|
|
243315
|
-
const declared = "1.4.
|
|
243336
|
+
const declared = "1.4.1";
|
|
243316
243337
|
if (declared) {
|
|
243317
243338
|
console.log(declared);
|
|
243318
243339
|
return;
|
package/package.json
CHANGED
package/src/cdp/detect.ts
CHANGED
|
@@ -1,4 +1,56 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A CDP-endpoint JSON probe that CANNOT leak a socket handle. Node's built-in
|
|
6
|
+
* `fetch` (undici) leaves a dangling socket + request handle when a
|
|
7
|
+
* connect-phase abort fires against a port that accepts TCP but never sends an
|
|
8
|
+
* HTTP response (e.g. a docker-proxied or half-open listener). That handle
|
|
9
|
+
* keeps this short-lived CLI process alive for undici's ~7s internal socket
|
|
10
|
+
* timeout AFTER all real work is done, so a single dead port on the machine
|
|
11
|
+
* adds ~7s to every command that runs port detection. A raw `http.get` whose
|
|
12
|
+
* request we explicitly `destroy()` on timeout releases the handle immediately.
|
|
13
|
+
*
|
|
14
|
+
* Resolves to the parsed JSON body on a 2xx response, or `null` on any
|
|
15
|
+
* timeout, connection error, non-2xx status, or unparseable body.
|
|
16
|
+
*/
|
|
17
|
+
function httpGetJson(
|
|
18
|
+
port: number,
|
|
19
|
+
path: string,
|
|
20
|
+
timeoutMs: number,
|
|
21
|
+
): Promise<unknown | null> {
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
const req = http.get(
|
|
24
|
+
{ host: 'localhost', port, path, timeout: timeoutMs },
|
|
25
|
+
(res) => {
|
|
26
|
+
const status = res.statusCode ?? 0;
|
|
27
|
+
if (status < 200 || status >= 300) {
|
|
28
|
+
res.resume();
|
|
29
|
+
resolve(null);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let body = '';
|
|
33
|
+
res.setEncoding('utf-8');
|
|
34
|
+
res.on('data', (chunk) => {
|
|
35
|
+
body += chunk;
|
|
36
|
+
});
|
|
37
|
+
res.on('end', () => {
|
|
38
|
+
try {
|
|
39
|
+
resolve(JSON.parse(body));
|
|
40
|
+
} catch {
|
|
41
|
+
resolve(null);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
res.on('error', () => resolve(null));
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
req.on('timeout', () => {
|
|
48
|
+
req.destroy();
|
|
49
|
+
resolve(null);
|
|
50
|
+
});
|
|
51
|
+
req.on('error', () => resolve(null));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
2
54
|
|
|
3
55
|
export const BROWSER_PATTERNS: Record<string, string[]> = {
|
|
4
56
|
'company.thebrowser.browser': ['arc'],
|
|
@@ -40,18 +92,12 @@ interface CdpProbeResult {
|
|
|
40
92
|
// being confused for the intended browser.
|
|
41
93
|
async function probeCdpPort(port: number): Promise<CdpProbeResult | null> {
|
|
42
94
|
try {
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (resp.ok) {
|
|
50
|
-
const version = (await resp.json()) as {
|
|
51
|
-
Browser?: string;
|
|
52
|
-
'User-Agent'?: string;
|
|
53
|
-
webSocketDebuggerUrl?: string;
|
|
54
|
-
};
|
|
95
|
+
const version = (await httpGetJson(port, '/json/version', 500)) as {
|
|
96
|
+
Browser?: string;
|
|
97
|
+
'User-Agent'?: string;
|
|
98
|
+
webSocketDebuggerUrl?: string;
|
|
99
|
+
} | null;
|
|
100
|
+
if (version) {
|
|
55
101
|
const browser = version.Browser;
|
|
56
102
|
const userAgent = version['User-Agent'] ?? '';
|
|
57
103
|
if (!browser) return null;
|
|
@@ -83,14 +129,9 @@ async function probeCdpPort(port: number): Promise<CdpProbeResult | null> {
|
|
|
83
129
|
|
|
84
130
|
async function probeHasPageTarget(port: number): Promise<boolean> {
|
|
85
131
|
try {
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
signal: controller.signal,
|
|
90
|
-
});
|
|
91
|
-
clearTimeout(timeout);
|
|
92
|
-
if (!resp.ok) return false;
|
|
93
|
-
const list = (await resp.json()) as Array<{ type?: string }>;
|
|
132
|
+
const list = (await httpGetJson(port, '/json/list', 500)) as Array<{
|
|
133
|
+
type?: string;
|
|
134
|
+
}> | null;
|
|
94
135
|
return Array.isArray(list) && list.some((t) => t.type === 'page');
|
|
95
136
|
} catch {
|
|
96
137
|
return false;
|