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 +17 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +17 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -151,6 +151,13 @@ interface SnapshotOptions {
|
|
|
151
151
|
* - `'role'` — uses Playwright's `ariaSnapshot()` + `getByRole()` resolution
|
|
152
152
|
*/
|
|
153
153
|
mode?: 'role' | 'aria';
|
|
154
|
+
/**
|
|
155
|
+
* How refs are stored for role-mode snapshots.
|
|
156
|
+
* - `'role'` (default) — refs resolved via `getByRole()`
|
|
157
|
+
* - `'aria'` — refs resolved via aria snapshot index
|
|
158
|
+
* Only applies when `mode: 'role'`.
|
|
159
|
+
*/
|
|
160
|
+
refsMode?: 'role' | 'aria';
|
|
154
161
|
}
|
|
155
162
|
/** A node in the raw ARIA accessibility tree. */
|
|
156
163
|
interface AriaNode {
|
package/dist/index.d.ts
CHANGED
|
@@ -151,6 +151,13 @@ interface SnapshotOptions {
|
|
|
151
151
|
* - `'role'` — uses Playwright's `ariaSnapshot()` + `getByRole()` resolution
|
|
152
152
|
*/
|
|
153
153
|
mode?: 'role' | 'aria';
|
|
154
|
+
/**
|
|
155
|
+
* How refs are stored for role-mode snapshots.
|
|
156
|
+
* - `'role'` (default) — refs resolved via `getByRole()`
|
|
157
|
+
* - `'aria'` — refs resolved via aria snapshot index
|
|
158
|
+
* Only applies when `mode: 'role'`.
|
|
159
|
+
*/
|
|
160
|
+
refsMode?: 'role' | 'aria';
|
|
154
161
|
}
|
|
155
162
|
/** A node in the raw ARIA accessibility tree. */
|
|
156
163
|
interface AriaNode {
|
package/dist/index.js
CHANGED
|
@@ -1104,7 +1104,7 @@ async function snapshotRole(opts) {
|
|
|
1104
1104
|
targetId: opts.targetId,
|
|
1105
1105
|
refs: built.refs,
|
|
1106
1106
|
frameSelector: frameSelector || void 0,
|
|
1107
|
-
mode: "role"
|
|
1107
|
+
mode: opts.refsMode ?? "role"
|
|
1108
1108
|
});
|
|
1109
1109
|
return {
|
|
1110
1110
|
snapshot: built.snapshot,
|
|
@@ -1387,7 +1387,20 @@ var InvalidBrowserNavigationUrlError = class extends Error {
|
|
|
1387
1387
|
function withBrowserNavigationPolicy(ssrfPolicy) {
|
|
1388
1388
|
return { ssrfPolicy };
|
|
1389
1389
|
}
|
|
1390
|
+
var NETWORK_NAVIGATION_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
|
|
1391
|
+
var SAFE_NON_NETWORK_URLS = /* @__PURE__ */ new Set(["about:blank"]);
|
|
1390
1392
|
async function assertBrowserNavigationAllowed(opts) {
|
|
1393
|
+
const rawUrl = String(opts.url ?? "").trim();
|
|
1394
|
+
let parsed;
|
|
1395
|
+
try {
|
|
1396
|
+
parsed = new URL(rawUrl);
|
|
1397
|
+
} catch {
|
|
1398
|
+
throw new InvalidBrowserNavigationUrlError(`Invalid URL: "${rawUrl}"`);
|
|
1399
|
+
}
|
|
1400
|
+
if (!NETWORK_NAVIGATION_PROTOCOLS.has(parsed.protocol)) {
|
|
1401
|
+
if (SAFE_NON_NETWORK_URLS.has(parsed.href)) return;
|
|
1402
|
+
throw new InvalidBrowserNavigationUrlError(`Navigation blocked: unsupported protocol "${parsed.protocol}"`);
|
|
1403
|
+
}
|
|
1391
1404
|
const policy = opts.ssrfPolicy;
|
|
1392
1405
|
if (policy?.allowPrivateNetwork) return;
|
|
1393
1406
|
const allowedHostnames = [
|
|
@@ -1395,18 +1408,12 @@ async function assertBrowserNavigationAllowed(opts) {
|
|
|
1395
1408
|
...policy?.hostnameAllowlist ?? []
|
|
1396
1409
|
];
|
|
1397
1410
|
if (allowedHostnames.length) {
|
|
1398
|
-
let parsed;
|
|
1399
|
-
try {
|
|
1400
|
-
parsed = new URL(opts.url);
|
|
1401
|
-
} catch {
|
|
1402
|
-
throw new InvalidBrowserNavigationUrlError(`Invalid URL: "${opts.url}"`);
|
|
1403
|
-
}
|
|
1404
1411
|
const hostname = parsed.hostname.toLowerCase();
|
|
1405
1412
|
if (allowedHostnames.some((h) => h.toLowerCase() === hostname)) return;
|
|
1406
1413
|
}
|
|
1407
|
-
if (await isInternalUrlResolved(
|
|
1414
|
+
if (await isInternalUrlResolved(rawUrl, opts.lookupFn)) {
|
|
1408
1415
|
throw new InvalidBrowserNavigationUrlError(
|
|
1409
|
-
`Navigation to internal/loopback address blocked: "${
|
|
1416
|
+
`Navigation to internal/loopback address blocked: "${rawUrl}". Use ssrfPolicy: { allowPrivateNetwork: true } if this is intentional.`
|
|
1410
1417
|
);
|
|
1411
1418
|
}
|
|
1412
1419
|
}
|
|
@@ -2136,6 +2143,7 @@ var CrawlPage = class {
|
|
|
2136
2143
|
targetId: this.targetId,
|
|
2137
2144
|
selector: opts.selector,
|
|
2138
2145
|
frameSelector: opts.frameSelector,
|
|
2146
|
+
refsMode: opts.refsMode,
|
|
2139
2147
|
options: {
|
|
2140
2148
|
interactive: opts.interactive,
|
|
2141
2149
|
compact: opts.compact,
|