browserclaw 0.3.3 → 0.3.5
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 +14 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -6
- package/dist/index.d.ts +19 -6
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -751,12 +751,13 @@ async function getPageForTargetId(opts) {
|
|
|
751
751
|
const found = await findPageByTargetId(browser, opts.targetId, opts.cdpUrl);
|
|
752
752
|
if (!found) {
|
|
753
753
|
if (pages.length === 1) return first;
|
|
754
|
-
throw new Error(
|
|
754
|
+
throw new Error(`Tab not found (targetId: ${opts.targetId}). Call browser.tabs() to list open tabs.`);
|
|
755
755
|
}
|
|
756
756
|
return found;
|
|
757
757
|
}
|
|
758
758
|
function refLocator(page, ref) {
|
|
759
759
|
const normalized = ref.startsWith("@") ? ref.slice(1) : ref.startsWith("ref=") ? ref.slice(4) : ref;
|
|
760
|
+
if (!normalized.trim()) throw new Error("ref is required");
|
|
760
761
|
if (/^e\d+$/.test(normalized)) {
|
|
761
762
|
const state = pageStates.get(page);
|
|
762
763
|
if (state?.roleRefsMode === "aria") {
|
|
@@ -1105,7 +1106,7 @@ async function snapshotRole(opts) {
|
|
|
1105
1106
|
const frameSelector = opts.frameSelector?.trim() || "";
|
|
1106
1107
|
const selector = opts.selector?.trim() || "";
|
|
1107
1108
|
const locator = frameSelector ? selector ? page.frameLocator(frameSelector).locator(selector) : page.frameLocator(frameSelector).locator(":root") : selector ? page.locator(selector) : page.locator(":root");
|
|
1108
|
-
const ariaSnapshot = await locator.ariaSnapshot({ timeout:
|
|
1109
|
+
const ariaSnapshot = await locator.ariaSnapshot({ timeout: normalizeTimeoutMs(opts.timeoutMs, 5e3) });
|
|
1109
1110
|
const built = buildRoleSnapshotFromAriaSnapshot(String(ariaSnapshot ?? ""), opts.options);
|
|
1110
1111
|
storeRoleRefsForTarget({
|
|
1111
1112
|
page,
|
|
@@ -1411,7 +1412,7 @@ async function assertBrowserNavigationAllowed(opts) {
|
|
|
1411
1412
|
throw new InvalidBrowserNavigationUrlError(`Navigation blocked: unsupported protocol "${parsed.protocol}"`);
|
|
1412
1413
|
}
|
|
1413
1414
|
const policy = opts.ssrfPolicy;
|
|
1414
|
-
if (policy?.allowPrivateNetwork) return;
|
|
1415
|
+
if (policy?.dangerouslyAllowPrivateNetwork ?? policy?.allowPrivateNetwork ?? true) return;
|
|
1415
1416
|
const allowedHostnames = [
|
|
1416
1417
|
...policy?.allowedHostnames ?? [],
|
|
1417
1418
|
...policy?.hostnameAllowlist ?? []
|
|
@@ -1422,7 +1423,7 @@ async function assertBrowserNavigationAllowed(opts) {
|
|
|
1422
1423
|
}
|
|
1423
1424
|
if (await isInternalUrlResolved(rawUrl, opts.lookupFn)) {
|
|
1424
1425
|
throw new InvalidBrowserNavigationUrlError(
|
|
1425
|
-
`Navigation to internal/loopback address blocked: "${rawUrl}".
|
|
1426
|
+
`Navigation to internal/loopback address blocked: "${rawUrl}". ssrfPolicy.dangerouslyAllowPrivateNetwork is false (strict mode).`
|
|
1426
1427
|
);
|
|
1427
1428
|
}
|
|
1428
1429
|
}
|
|
@@ -1569,7 +1570,7 @@ async function isInternalUrlResolved(url, lookupFn = promises.lookup) {
|
|
|
1569
1570
|
async function navigateViaPlaywright(opts) {
|
|
1570
1571
|
const url = String(opts.url ?? "").trim();
|
|
1571
1572
|
if (!url) throw new Error("url is required");
|
|
1572
|
-
const policy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
1573
|
+
const policy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
1573
1574
|
await assertBrowserNavigationAllowed({ url, ssrfPolicy: policy });
|
|
1574
1575
|
const page = await getPageForTargetId({ cdpUrl: opts.cdpUrl, targetId: opts.targetId });
|
|
1575
1576
|
ensurePageState(page);
|
|
@@ -1594,7 +1595,7 @@ async function listPagesViaPlaywright(opts) {
|
|
|
1594
1595
|
async function createPageViaPlaywright(opts) {
|
|
1595
1596
|
const targetUrl = (opts.url ?? "").trim() || "about:blank";
|
|
1596
1597
|
if (targetUrl !== "about:blank") {
|
|
1597
|
-
const policy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
1598
|
+
const policy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
1598
1599
|
await assertBrowserNavigationAllowed({ url: targetUrl, ssrfPolicy: policy });
|
|
1599
1600
|
}
|
|
1600
1601
|
const { browser } = await connectBrowser(opts.cdpUrl);
|
|
@@ -1834,7 +1835,7 @@ async function setGeolocationViaPlaywright(opts) {
|
|
|
1834
1835
|
return;
|
|
1835
1836
|
}
|
|
1836
1837
|
if (opts.latitude === void 0 || opts.longitude === void 0) {
|
|
1837
|
-
throw new Error("latitude and longitude are required
|
|
1838
|
+
throw new Error("latitude and longitude are required (or set clear=true)");
|
|
1838
1839
|
}
|
|
1839
1840
|
await context.grantPermissions(["geolocation"], opts.origin ? { origin: opts.origin } : void 0);
|
|
1840
1841
|
await context.setGeolocation({
|
|
@@ -1981,8 +1982,9 @@ async function responseBodyViaPlaywright(opts) {
|
|
|
1981
1982
|
const response = await page.waitForResponse(opts.url, { timeout });
|
|
1982
1983
|
let body = await response.text();
|
|
1983
1984
|
let truncated = false;
|
|
1984
|
-
|
|
1985
|
-
|
|
1985
|
+
const maxChars = typeof opts.maxChars === "number" && Number.isFinite(opts.maxChars) ? Math.max(1, Math.min(5e6, Math.floor(opts.maxChars))) : void 0;
|
|
1986
|
+
if (maxChars !== void 0 && body.length > maxChars) {
|
|
1987
|
+
body = body.slice(0, maxChars);
|
|
1986
1988
|
truncated = true;
|
|
1987
1989
|
}
|
|
1988
1990
|
const headers = {};
|
|
@@ -2153,6 +2155,7 @@ var CrawlPage = class {
|
|
|
2153
2155
|
selector: opts.selector,
|
|
2154
2156
|
frameSelector: opts.frameSelector,
|
|
2155
2157
|
refsMode: opts.refsMode,
|
|
2158
|
+
timeoutMs: opts.timeoutMs,
|
|
2156
2159
|
options: {
|
|
2157
2160
|
interactive: opts.interactive,
|
|
2158
2161
|
compact: opts.compact,
|
|
@@ -3016,7 +3019,7 @@ var BrowserClaw = class _BrowserClaw {
|
|
|
3016
3019
|
static async launch(opts = {}) {
|
|
3017
3020
|
const chrome = await launchChrome(opts);
|
|
3018
3021
|
const cdpUrl = `http://127.0.0.1:${chrome.cdpPort}`;
|
|
3019
|
-
const ssrfPolicy = opts.allowInternal ? { ...opts.ssrfPolicy,
|
|
3022
|
+
const ssrfPolicy = opts.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts.ssrfPolicy;
|
|
3020
3023
|
return new _BrowserClaw(cdpUrl, chrome, ssrfPolicy);
|
|
3021
3024
|
}
|
|
3022
3025
|
/**
|
|
@@ -3038,7 +3041,7 @@ var BrowserClaw = class _BrowserClaw {
|
|
|
3038
3041
|
throw new Error(`Cannot connect to Chrome at ${cdpUrl}. Is Chrome running with --remote-debugging-port?`);
|
|
3039
3042
|
}
|
|
3040
3043
|
await connectBrowser(cdpUrl, opts?.authToken);
|
|
3041
|
-
const ssrfPolicy = opts?.allowInternal ? { ...opts.ssrfPolicy,
|
|
3044
|
+
const ssrfPolicy = opts?.allowInternal ? { ...opts.ssrfPolicy, dangerouslyAllowPrivateNetwork: true } : opts?.ssrfPolicy;
|
|
3042
3045
|
return new _BrowserClaw(cdpUrl, null, ssrfPolicy);
|
|
3043
3046
|
}
|
|
3044
3047
|
/**
|