barebrowse 0.17.0 → 0.19.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/CHANGELOG.md +87 -0
- package/README.md +27 -25
- package/barebrowse.context.md +1 -1
- package/cli.js +1 -1
- package/mcp-server.js +6 -4
- package/package.json +1 -1
- package/src/bidi.js +8 -2
- package/src/blocklist-firefox.js +60 -0
- package/src/blocklist.js +49 -0
- package/src/challenge.js +77 -0
- package/src/dialog.js +52 -0
- package/src/firefox-page.js +209 -21
- package/src/firefox.js +15 -0
- package/src/index.js +84 -116
- package/types/blocklist-firefox.d.ts +15 -0
- package/types/blocklist.d.ts +34 -0
- package/types/challenge.d.ts +25 -0
- package/types/dialog.d.ts +44 -0
- package/types/firefox-page.d.ts +9 -0
- package/types/firefox.d.ts +2 -0
- package/types/index.d.ts +2 -18
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dialog.js — Shared JS-dialog decision core for both engines.
|
|
3
|
+
*
|
|
4
|
+
* A JS dialog (alert/confirm/prompt/beforeunload) surfaces differently per
|
|
5
|
+
* protocol — CDP's `Page.javascriptDialogOpening` vs BiDi's
|
|
6
|
+
* `browsingContext.userPromptOpened` — but the *decision* (accept? what prompt
|
|
7
|
+
* text?) and the log entry are identical. This module single-sources both so
|
|
8
|
+
* the CDP path (index.js) and the BiDi path (firefox-page.js) can't drift
|
|
9
|
+
* (code-review Phase-3 finding #5).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Build a dialogLog entry from a normalized dialog descriptor.
|
|
13
|
+
* @param {string} type - 'alert' | 'confirm' | 'prompt' | 'beforeunload'
|
|
14
|
+
* @param {string} [message]
|
|
15
|
+
* @returns {{type: string, message: string, timestamp: string}}
|
|
16
|
+
*/
|
|
17
|
+
export function dialogLogEntry(type: string, message?: string): {
|
|
18
|
+
type: string;
|
|
19
|
+
message: string;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Decide how to answer a JS dialog. Default policy (both engines): accept
|
|
24
|
+
* everything except `beforeunload` (dismiss = stay on page); a `prompt`
|
|
25
|
+
* returns its default text. A caller-installed handler may override via
|
|
26
|
+
* `{ accept, promptText }`; if the handler throws we keep the defaults so the
|
|
27
|
+
* page never hangs waiting for a reply that never arrives.
|
|
28
|
+
*
|
|
29
|
+
* @param {{type: string, message?: string, defaultPrompt?: string}} dialog
|
|
30
|
+
* @param {?(function({type,message,defaultPrompt}): (object|Promise<object>))} handler
|
|
31
|
+
* @returns {Promise<{accept: boolean, promptText: string}>}
|
|
32
|
+
*/
|
|
33
|
+
export function decideDialog({ type, message, defaultPrompt }: {
|
|
34
|
+
type: string;
|
|
35
|
+
message?: string;
|
|
36
|
+
defaultPrompt?: string;
|
|
37
|
+
}, handler: ((arg0: {
|
|
38
|
+
type: any;
|
|
39
|
+
message: any;
|
|
40
|
+
defaultPrompt: any;
|
|
41
|
+
}) => (object | Promise<object>)) | null): Promise<{
|
|
42
|
+
accept: boolean;
|
|
43
|
+
promptText: string;
|
|
44
|
+
}>;
|
package/types/firefox-page.d.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* @param {string} [opts.uploadDir] - When set, upload() rejects files outside this dir.
|
|
8
8
|
* @param {boolean} [opts.incognito=false] - Clean session: injectCookies() is a no-op.
|
|
9
9
|
* @param {boolean} [opts.consent=true] - Auto-dismiss cookie consent dialogs after goto().
|
|
10
|
+
* @param {boolean} [opts.hybrid=false] - Relaunch headed on a bot-challenge page and retry.
|
|
11
|
+
* @param {boolean} [opts.headed=false] - Whether the browser was launched headed (skips hybrid fallback).
|
|
12
|
+
* @param {?function(): Promise<{bidi: object, topContext: string}>} [opts.relaunchHeaded] - Hybrid relaunch hook (from connectFirefox).
|
|
10
13
|
* @returns {Promise<object>} page object
|
|
11
14
|
*/
|
|
12
15
|
export function createFirefoxPage(bidi: object, opts?: {
|
|
@@ -18,4 +21,10 @@ export function createFirefoxPage(bidi: object, opts?: {
|
|
|
18
21
|
uploadDir?: string | undefined;
|
|
19
22
|
incognito?: boolean | undefined;
|
|
20
23
|
consent?: boolean | undefined;
|
|
24
|
+
hybrid?: boolean | undefined;
|
|
25
|
+
headed?: boolean | undefined;
|
|
26
|
+
relaunchHeaded?: (() => Promise<{
|
|
27
|
+
bidi: object;
|
|
28
|
+
topContext: string;
|
|
29
|
+
}>) | null | undefined;
|
|
21
30
|
}): Promise<object>;
|
package/types/firefox.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export function findFirefox(): string;
|
|
|
14
14
|
* @param {string} [opts.proxy] - Proxy 'host:port' or 'scheme://host:port'
|
|
15
15
|
* (http/https → HTTP+SSL proxy; socks/socks5/socks4 → SOCKS), via prefs
|
|
16
16
|
* @param {{width:number,height:number}} [opts.viewport] - Initial window size
|
|
17
|
+
* @param {string} [opts.downloadDir] - Route downloads here (throwaway dir), no prompt
|
|
17
18
|
* @returns {Promise<{wsUrl: string, process: import('node:child_process').ChildProcess, port: number, ownedProfileDir: string}>}
|
|
18
19
|
*/
|
|
19
20
|
export function launchFirefox(opts?: {
|
|
@@ -25,6 +26,7 @@ export function launchFirefox(opts?: {
|
|
|
25
26
|
width: number;
|
|
26
27
|
height: number;
|
|
27
28
|
} | undefined;
|
|
29
|
+
downloadDir?: string | undefined;
|
|
28
30
|
}): Promise<{
|
|
29
31
|
wsUrl: string;
|
|
30
32
|
process: import("node:child_process").ChildProcess;
|
package/types/index.d.ts
CHANGED
|
@@ -129,21 +129,5 @@ export function connect(opts?: {
|
|
|
129
129
|
export function applyBlocklist(session: any, pageOpts: any): Promise<void>;
|
|
130
130
|
/** Test-only: reset the warn-once flag. Not part of the public API. */
|
|
131
131
|
export function _resetBlocklistWarning(): void;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
*
|
|
135
|
-
* Pre-H9 this was over-aggressive: `nodeCount < 50` alone fired on any
|
|
136
|
-
* legitimate small page (404s, simple landings, error pages), and generic
|
|
137
|
-
* phrases like "access denied" / "unknown error" / "permission denied"
|
|
138
|
-
* triggered on real HTTP 4xx/5xx pages, kicking hybrid mode into a costly
|
|
139
|
-
* headed fallback for nothing.
|
|
140
|
-
*
|
|
141
|
-
* H9 split: STRONG_PHRASES are essentially-unambiguous challenge UI and
|
|
142
|
-
* fire regardless of page size; WEAK_PHRASES only fire when the page is
|
|
143
|
-
* ALSO tiny (so a legitimate-looking error page with "access denied" in
|
|
144
|
-
* its body doesn't trip the fallback).
|
|
145
|
-
*
|
|
146
|
-
* @param {object} tree - Nested ARIA tree (from buildTree)
|
|
147
|
-
* @param {number} [nodeCount] - Raw CDP node count (from Accessibility.getFullAXTree)
|
|
148
|
-
*/
|
|
149
|
-
export function isChallengePage(tree: object, nodeCount?: number): boolean;
|
|
132
|
+
export { isChallengePage };
|
|
133
|
+
import { isChallengePage } from './challenge.js';
|