cloakbrowser 0.3.22 → 0.3.24

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.
Files changed (41) hide show
  1. package/README.md +5 -2
  2. package/dist/config.js +2 -2
  3. package/dist/geoip.d.ts.map +1 -1
  4. package/dist/geoip.js +62 -8
  5. package/dist/geoip.js.map +1 -1
  6. package/dist/human/elementhandle.d.ts +30 -0
  7. package/dist/human/elementhandle.d.ts.map +1 -0
  8. package/dist/human/elementhandle.js +317 -0
  9. package/dist/human/elementhandle.js.map +1 -0
  10. package/dist/human/index.d.ts +9 -0
  11. package/dist/human/index.d.ts.map +1 -1
  12. package/dist/human/index.js +25 -2
  13. package/dist/human/index.js.map +1 -1
  14. package/dist/human-puppeteer/index.d.ts +63 -0
  15. package/dist/human-puppeteer/index.d.ts.map +1 -0
  16. package/dist/human-puppeteer/index.js +780 -0
  17. package/dist/human-puppeteer/index.js.map +1 -0
  18. package/dist/human-puppeteer/keyboard.d.ts +16 -0
  19. package/dist/human-puppeteer/keyboard.d.ts.map +1 -0
  20. package/dist/human-puppeteer/keyboard.js +157 -0
  21. package/dist/human-puppeteer/keyboard.js.map +1 -0
  22. package/dist/human-puppeteer/scroll.d.ts +26 -0
  23. package/dist/human-puppeteer/scroll.d.ts.map +1 -0
  24. package/dist/human-puppeteer/scroll.js +130 -0
  25. package/dist/human-puppeteer/scroll.js.map +1 -0
  26. package/dist/playwright.d.ts.map +1 -1
  27. package/dist/playwright.js +7 -9
  28. package/dist/playwright.js.map +1 -1
  29. package/dist/proxy.d.ts +29 -0
  30. package/dist/proxy.d.ts.map +1 -1
  31. package/dist/proxy.js +44 -4
  32. package/dist/proxy.js.map +1 -1
  33. package/dist/puppeteer.d.ts +7 -5
  34. package/dist/puppeteer.d.ts.map +1 -1
  35. package/dist/puppeteer.js +26 -15
  36. package/dist/puppeteer.js.map +1 -1
  37. package/package.json +12 -3
  38. package/dist/stealth-eval.d.ts +0 -40
  39. package/dist/stealth-eval.d.ts.map +0 -1
  40. package/dist/stealth-eval.js +0 -145
  41. package/dist/stealth-eval.js.map +0 -1
package/dist/proxy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,QAAQ,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,GAAQ,CAAC;IACb,0EAA0E;IAC1E,MAAM,UAAU,GACd,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAC5E,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,mEAAmE;QACnE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,yCAAyC;IACzC,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAEnF,MAAM,MAAM,GAAgB;QAC1B,MAAM;QACN,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;KAC3C,CAAC;IACF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,MAAM,CAAC,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Puppeteer launch wrapper for cloakbrowser.
3
- * Alternative to the Playwright wrapper for users who prefer Puppeteer.
3
+ * NOW WITH HUMANIZE SUPPORT humanize: true enables human-like
4
+ * mouse curves, keyboard timing, and scroll patterns (same as Playwright).
4
5
  */
5
6
  import type { Browser } from "puppeteer-core";
6
7
  import type { LaunchOptions } from "./types.js";
@@ -10,11 +11,12 @@ import type { LaunchOptions } from "./types.js";
10
11
  * @example
11
12
  * ```ts
12
13
  * import { launch } from 'cloakbrowser/puppeteer';
13
- * const browser = await launch();
14
+ * * // With humanize — human-like mouse, keyboard, scroll
15
+ * const browser = await launch({ humanize: true });
14
16
  * const page = await browser.newPage();
15
- * await page.goto('https://bot.incolumitas.com');
16
- * console.log(await page.title());
17
- * await browser.close();
17
+ * await page.goto('[https://example.com](https://example.com)');
18
+ * await page.click('#login'); // Bézier curve mouse movement
19
+ * await page.type('#email', 'user@example.com'); // Per-character timing
18
20
  * ```
19
21
  */
20
22
  export declare function launch(options?: LaunchOptions): Promise<Browser>;
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer.d.ts","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2D1E"}
1
+ {"version":3,"file":"puppeteer.d.ts","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAOhD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2E1E"}
package/dist/puppeteer.js CHANGED
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * Puppeteer launch wrapper for cloakbrowser.
3
- * Alternative to the Playwright wrapper for users who prefer Puppeteer.
3
+ * NOW WITH HUMANIZE SUPPORT humanize: true enables human-like
4
+ * mouse curves, keyboard timing, and scroll patterns (same as Playwright).
4
5
  */
5
6
  import { IGNORE_DEFAULT_ARGS } from "./config.js";
6
7
  import { buildArgs } from "./args.js";
7
8
  import { ensureBinary } from "./download.js";
8
- import { parseProxyUrl } from "./proxy.js";
9
+ import { isSocksProxy, parseProxyUrl, resolveProxyConfig } from "./proxy.js";
9
10
  import { maybeResolveGeoip, resolveWebrtcArgs } from "./geoip.js";
10
11
  /**
11
12
  * Launch stealth Chromium browser via Puppeteer.
@@ -13,11 +14,12 @@ import { maybeResolveGeoip, resolveWebrtcArgs } from "./geoip.js";
13
14
  * @example
14
15
  * ```ts
15
16
  * import { launch } from 'cloakbrowser/puppeteer';
16
- * const browser = await launch();
17
+ * * // With humanize — human-like mouse, keyboard, scroll
18
+ * const browser = await launch({ humanize: true });
17
19
  * const page = await browser.newPage();
18
- * await page.goto('https://bot.incolumitas.com');
19
- * console.log(await page.title());
20
- * await browser.close();
20
+ * await page.goto('[https://example.com](https://example.com)');
21
+ * await page.click('#login'); // Bézier curve mouse movement
22
+ * await page.type('#email', 'user@example.com'); // Per-character timing
21
23
  * ```
22
24
  */
23
25
  export async function launch(options = {}) {
@@ -30,11 +32,17 @@ export async function launch(options = {}) {
30
32
  }
31
33
  const args = buildArgs({ ...options, ...resolved, args: resolvedArgs });
32
34
  // Puppeteer handles proxy via CLI args, not a separate option.
33
- // Chromium's --proxy-server does NOT support inline credentials,
34
- // so we strip them and use page.authenticate() instead.
35
+ // SOCKS5: Chrome supports inline credentials natively (RFC 1929 auth).
36
+ // HTTP: Chrome does NOT support inline credentials — strip them and
37
+ // use page.authenticate() for Proxy-Authorization headers instead.
35
38
  let proxyAuth;
36
39
  if (options.proxy) {
37
- if (typeof options.proxy === "string") {
40
+ if (isSocksProxy(options.proxy)) {
41
+ // SOCKS5: pass full URL with credentials to Chrome directly
42
+ const { proxyArgs } = resolveProxyConfig(options.proxy);
43
+ args.push(...proxyArgs);
44
+ }
45
+ else if (typeof options.proxy === "string") {
38
46
  const { server, username, password } = parseProxyUrl(options.proxy);
39
47
  args.push(`--proxy-server=${server}`);
40
48
  if (username) {
@@ -42,14 +50,11 @@ export async function launch(options = {}) {
42
50
  }
43
51
  }
44
52
  else {
45
- // Strip any inline credentials from the server URL — Chromium's
46
- // --proxy-server doesn't support them; use page.authenticate() instead.
47
53
  const parsed = parseProxyUrl(options.proxy.server);
48
54
  args.push(`--proxy-server=${parsed.server}`);
49
55
  if (options.proxy.bypass) {
50
56
  args.push(`--proxy-bypass-list=${options.proxy.bypass}`);
51
57
  }
52
- // Explicit username/password fields take precedence over inline creds
53
58
  const username = options.proxy.username ?? parsed.username;
54
59
  const password = options.proxy.password ?? parsed.password;
55
60
  if (username) {
@@ -74,9 +79,15 @@ export async function launch(options = {}) {
74
79
  return page;
75
80
  };
76
81
  }
82
+ // Human-like behavioral patching — FULL coverage, same as Playwright.
83
+ // This enables Bézier mouse movements, organic typing rhythms, and
84
+ // natural scrolling to bypass advanced anti-bot detection.
85
+ if (options.humanize) {
86
+ const { patchBrowser } = await import('./human-puppeteer/index.js');
87
+ const { resolveConfig } = await import('./human/config.js');
88
+ const cfg = resolveConfig(options.humanPreset ?? 'default', options.humanConfig);
89
+ patchBrowser(browser, cfg);
90
+ }
77
91
  return browser;
78
92
  }
79
- // ---------------------------------------------------------------------------
80
- // Internal
81
- // ---------------------------------------------------------------------------
82
93
  //# sourceMappingURL=puppeteer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"puppeteer.js","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"puppeteer.js","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,UAAyB,EAAE;IACtD,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;IAClF,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,GAAG,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACzE,IAAI,YAAY,GAAG,CAAC,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAEtE,IAAI,MAAM,IAAI,CAAC,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC;QACvF,YAAY,GAAG,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,2BAA2B,MAAM,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,IAAI,GAAG,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;IAExE,+DAA+D;IAC/D,uEAAuE;IACvE,oEAAoE;IACpE,mEAAmE;IACnE,IAAI,SAA6D,CAAC;IAClE,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,4DAA4D;YAC5D,MAAM,EAAE,SAAS,EAAE,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC7C,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACpE,IAAI,CAAC,IAAI,CAAC,kBAAkB,MAAM,EAAE,CAAC,CAAC;YACtC,IAAI,QAAQ,EAAE,CAAC;gBACb,SAAS,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;YACrD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,IAAI,CAAC,IAAI,CAAC,uBAAuB,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;YAC3D,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC;YAC3D,IAAI,QAAQ,EAAE,CAAC;gBACb,SAAS,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC;QAC7C,cAAc,EAAE,UAAU;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;QAClC,IAAI;QACJ,iBAAiB,EAAE,mBAAmB;QACtC,GAAG,OAAO,CAAC,aAAa;KACzB,CAAC,CAAC;IAEH,gEAAgE;IAChE,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,SAAS,CAAC;QACvB,OAAO,CAAC,OAAO,GAAG,KAAK,EAAE,GAAG,QAAwC,EAAE,EAAE;YACtE,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,oEAAoE;IACpE,2DAA2D;IAC3D,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,4BAA4B,CAAC,CAAC;QACpE,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,aAAa,CACtB,OAAO,CAAC,WAAmB,IAAI,SAAS,EACzC,OAAO,CAAC,WAAkB,CAC3B,CAAC;QACF,YAAY,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloakbrowser",
3
- "version": "0.3.22",
3
+ "version": "0.3.24",
4
4
  "description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,6 +13,10 @@
13
13
  "./puppeteer": {
14
14
  "types": "./dist/puppeteer.d.ts",
15
15
  "import": "./dist/puppeteer.js"
16
+ },
17
+ "./human": {
18
+ "types": "./dist/human/index.d.ts",
19
+ "import": "./dist/human/index.js"
16
20
  }
17
21
  },
18
22
  "bin": {
@@ -51,12 +55,13 @@
51
55
  },
52
56
  "homepage": "https://github.com/CloakHQ/cloakbrowser#javascript--nodejs",
53
57
  "engines": {
54
- "node": ">=18.0.0"
58
+ "node": ">=20.0.0"
55
59
  },
56
60
  "peerDependencies": {
57
61
  "mmdb-lib": ">=2.0.0",
58
62
  "playwright-core": ">=1.40.0",
59
- "puppeteer-core": ">=21.0.0"
63
+ "puppeteer-core": ">=21.0.0",
64
+ "socks-proxy-agent": ">=10.0.0"
60
65
  },
61
66
  "peerDependenciesMeta": {
62
67
  "playwright-core": {
@@ -67,6 +72,9 @@
67
72
  },
68
73
  "mmdb-lib": {
69
74
  "optional": true
75
+ },
76
+ "socks-proxy-agent": {
77
+ "optional": true
70
78
  }
71
79
  },
72
80
  "dependencies": {
@@ -75,6 +83,7 @@
75
83
  "devDependencies": {
76
84
  "@types/node": "^20.10.0",
77
85
  "mmdb-lib": "^3.0.2",
86
+ "socks-proxy-agent": "^10.0.0",
78
87
  "playwright-core": "^1.40.0",
79
88
  "puppeteer-core": "^21.0.0",
80
89
  "typescript": "^5.3.0",
@@ -1,40 +0,0 @@
1
- /**
2
- * Stealth evaluate — run JS in a CDP isolated world.
3
- *
4
- * Provides page.stealthEvaluate(expression) on every page returned by
5
- * cloakbrowser launch functions. Produces clean Error.stack traces (no
6
- * `eval at evaluate :302:` leak) and full variable isolation from main
7
- * world JS. Context auto-recreates after navigation.
8
- *
9
- * The same StealthEval instances are reused by the humanize layer
10
- * (human/index.ts) for stealth DOM queries.
11
- */
12
- import type { Browser, BrowserContext, Page, CDPSession } from 'playwright-core';
13
- /**
14
- * Manages a CDP isolated execution context for DOM reads.
15
- * Produces clean Error.stack traces (no 'eval at evaluate :302:')
16
- * and is invisible to querySelector monkey-patches in the main world.
17
- *
18
- * Context ID is invalidated on navigation and auto-recreated on next call.
19
- */
20
- export declare class StealthEval {
21
- private cdp;
22
- private contextId;
23
- private page;
24
- constructor(page: Page);
25
- private ensureCdp;
26
- private createWorld;
27
- /**
28
- * Evaluate a JS expression in the isolated world.
29
- * Auto-recreates the world if the context was invalidated (navigation).
30
- * Returns the result value, or undefined on failure.
31
- */
32
- evaluate(expression: string): Promise<any>;
33
- /** Mark context as stale — call after navigation. */
34
- invalidate(): void;
35
- /** Get the underlying CDP session (reused for Input.dispatchKeyEvent etc.). */
36
- getCdpSession(): Promise<CDPSession>;
37
- }
38
- export declare function patchContext(context: BrowserContext): void;
39
- export declare function patchBrowser(browser: Browser): void;
40
- //# sourceMappingURL=stealth-eval.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stealth-eval.d.ts","sourceRoot":"","sources":["../src/stealth-eval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAOjF;;;;;;GAMG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,GAAG,CAA2B;IACtC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,IAAI,CAAO;gBAEP,IAAI,EAAE,IAAI;YAIR,SAAS;YAOT,WAAW;IAczB;;;;OAIG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IA2ChD,qDAAqD;IACrD,UAAU,IAAI,IAAI;IAIlB,+EAA+E;IACzE,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;CAG3C;AAeD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAe1D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAenD"}
@@ -1,145 +0,0 @@
1
- /**
2
- * Stealth evaluate — run JS in a CDP isolated world.
3
- *
4
- * Provides page.stealthEvaluate(expression) on every page returned by
5
- * cloakbrowser launch functions. Produces clean Error.stack traces (no
6
- * `eval at evaluate :302:` leak) and full variable isolation from main
7
- * world JS. Context auto-recreates after navigation.
8
- *
9
- * The same StealthEval instances are reused by the humanize layer
10
- * (human/index.ts) for stealth DOM queries.
11
- */
12
- // ============================================================================
13
- // Isolated world class
14
- // ============================================================================
15
- /**
16
- * Manages a CDP isolated execution context for DOM reads.
17
- * Produces clean Error.stack traces (no 'eval at evaluate :302:')
18
- * and is invisible to querySelector monkey-patches in the main world.
19
- *
20
- * Context ID is invalidated on navigation and auto-recreated on next call.
21
- */
22
- export class StealthEval {
23
- cdp = null;
24
- contextId = null;
25
- page;
26
- constructor(page) {
27
- this.page = page;
28
- }
29
- async ensureCdp() {
30
- if (!this.cdp) {
31
- this.cdp = await this.page.context().newCDPSession(this.page);
32
- }
33
- return this.cdp;
34
- }
35
- async createWorld() {
36
- const cdp = await this.ensureCdp();
37
- const tree = await cdp.send('Page.getFrameTree');
38
- const frameId = tree.frameTree.frame.id;
39
- const result = await cdp.send('Page.createIsolatedWorld', {
40
- frameId,
41
- worldName: '',
42
- grantUniveralAccess: true,
43
- });
44
- const ctxId = result.executionContextId;
45
- this.contextId = ctxId;
46
- return ctxId;
47
- }
48
- /**
49
- * Evaluate a JS expression in the isolated world.
50
- * Auto-recreates the world if the context was invalidated (navigation).
51
- * Returns the result value, or undefined on failure.
52
- */
53
- async evaluate(expression) {
54
- if (this.contextId === null) {
55
- try {
56
- await this.createWorld();
57
- }
58
- catch {
59
- return undefined;
60
- }
61
- }
62
- for (let attempt = 0; attempt < 2; attempt++) {
63
- try {
64
- const cdp = await this.ensureCdp();
65
- const result = await cdp.send('Runtime.evaluate', {
66
- expression,
67
- contextId: this.contextId,
68
- returnByValue: true,
69
- });
70
- if (result.exceptionDetails) {
71
- if (attempt === 0) {
72
- await this.createWorld();
73
- continue;
74
- }
75
- return undefined;
76
- }
77
- return result.result?.value;
78
- }
79
- catch {
80
- if (attempt === 0) {
81
- this.contextId = null;
82
- try {
83
- await this.createWorld();
84
- }
85
- catch {
86
- return undefined;
87
- }
88
- continue;
89
- }
90
- return undefined;
91
- }
92
- }
93
- return undefined;
94
- }
95
- /** Mark context as stale — call after navigation. */
96
- invalidate() {
97
- this.contextId = null;
98
- }
99
- /** Get the underlying CDP session (reused for Input.dispatchKeyEvent etc.). */
100
- async getCdpSession() {
101
- return this.ensureCdp();
102
- }
103
- }
104
- // ============================================================================
105
- // Page / context / browser patching
106
- // ============================================================================
107
- function patchPage(page) {
108
- if (page.stealthEvaluate)
109
- return;
110
- const existing = page._stealthWorld;
111
- const stealth = existing instanceof StealthEval ? existing : new StealthEval(page);
112
- page._stealthWorld = stealth;
113
- page.stealthEvaluate = stealth.evaluate.bind(stealth);
114
- }
115
- export function patchContext(context) {
116
- if (context._stealthEvalPatched)
117
- return;
118
- context._stealthEvalPatched = true;
119
- for (const p of context.pages()) {
120
- patchPage(p);
121
- }
122
- const origNewPage = context.newPage.bind(context);
123
- context.newPage = async (...args) => {
124
- const page = await origNewPage(...args);
125
- patchPage(page);
126
- return page;
127
- };
128
- context.on('page', (page) => patchPage(page));
129
- }
130
- export function patchBrowser(browser) {
131
- const origNewContext = browser.newContext.bind(browser);
132
- browser.newContext = async (...args) => {
133
- const ctx = await origNewContext(...args);
134
- patchContext(ctx);
135
- return ctx;
136
- };
137
- const origNewPage = browser.newPage.bind(browser);
138
- browser.newPage = async (...args) => {
139
- const page = await origNewPage(...args);
140
- patchContext(page.context());
141
- patchPage(page);
142
- return page;
143
- };
144
- }
145
- //# sourceMappingURL=stealth-eval.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stealth-eval.js","sourceRoot":"","sources":["../src/stealth-eval.ts"],"names":[],"mappings":"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"}