browserclaw 0.3.0 → 0.3.2

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 CHANGED
@@ -1113,7 +1113,7 @@ async function snapshotRole(opts) {
1113
1113
  targetId: opts.targetId,
1114
1114
  refs: built.refs,
1115
1115
  frameSelector: frameSelector || void 0,
1116
- mode: "role"
1116
+ mode: opts.refsMode ?? "role"
1117
1117
  });
1118
1118
  return {
1119
1119
  snapshot: built.snapshot,
@@ -1396,7 +1396,20 @@ var InvalidBrowserNavigationUrlError = class extends Error {
1396
1396
  function withBrowserNavigationPolicy(ssrfPolicy) {
1397
1397
  return { ssrfPolicy };
1398
1398
  }
1399
+ var NETWORK_NAVIGATION_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
1400
+ var SAFE_NON_NETWORK_URLS = /* @__PURE__ */ new Set(["about:blank"]);
1399
1401
  async function assertBrowserNavigationAllowed(opts) {
1402
+ const rawUrl = String(opts.url ?? "").trim();
1403
+ let parsed;
1404
+ try {
1405
+ parsed = new URL(rawUrl);
1406
+ } catch {
1407
+ throw new InvalidBrowserNavigationUrlError(`Invalid URL: "${rawUrl}"`);
1408
+ }
1409
+ if (!NETWORK_NAVIGATION_PROTOCOLS.has(parsed.protocol)) {
1410
+ if (SAFE_NON_NETWORK_URLS.has(parsed.href)) return;
1411
+ throw new InvalidBrowserNavigationUrlError(`Navigation blocked: unsupported protocol "${parsed.protocol}"`);
1412
+ }
1400
1413
  const policy = opts.ssrfPolicy;
1401
1414
  if (policy?.allowPrivateNetwork) return;
1402
1415
  const allowedHostnames = [
@@ -1404,18 +1417,12 @@ async function assertBrowserNavigationAllowed(opts) {
1404
1417
  ...policy?.hostnameAllowlist ?? []
1405
1418
  ];
1406
1419
  if (allowedHostnames.length) {
1407
- let parsed;
1408
- try {
1409
- parsed = new URL(opts.url);
1410
- } catch {
1411
- throw new InvalidBrowserNavigationUrlError(`Invalid URL: "${opts.url}"`);
1412
- }
1413
1420
  const hostname = parsed.hostname.toLowerCase();
1414
1421
  if (allowedHostnames.some((h) => h.toLowerCase() === hostname)) return;
1415
1422
  }
1416
- if (await isInternalUrlResolved(opts.url, opts.lookupFn)) {
1423
+ if (await isInternalUrlResolved(rawUrl, opts.lookupFn)) {
1417
1424
  throw new InvalidBrowserNavigationUrlError(
1418
- `Navigation to internal/loopback address blocked: "${opts.url}". Use ssrfPolicy: { allowPrivateNetwork: true } if this is intentional.`
1425
+ `Navigation to internal/loopback address blocked: "${rawUrl}". Use ssrfPolicy: { allowPrivateNetwork: true } if this is intentional.`
1419
1426
  );
1420
1427
  }
1421
1428
  }
@@ -2145,6 +2152,7 @@ var CrawlPage = class {
2145
2152
  targetId: this.targetId,
2146
2153
  selector: opts.selector,
2147
2154
  frameSelector: opts.frameSelector,
2155
+ refsMode: opts.refsMode,
2148
2156
  options: {
2149
2157
  interactive: opts.interactive,
2150
2158
  compact: opts.compact,