cloakbrowser 0.2.0 → 0.2.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/README.md +34 -1
- package/dist/geoip.d.ts +24 -0
- package/dist/geoip.d.ts.map +1 -0
- package/dist/geoip.js +233 -0
- package/dist/geoip.js.map +1 -0
- package/dist/playwright.d.ts.map +1 -1
- package/dist/playwright.js +26 -4
- package/dist/playwright.js.map +1 -1
- package/dist/puppeteer.d.ts.map +1 -1
- package/dist/puppeteer.js +20 -1
- package/dist/puppeteer.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -75,7 +75,19 @@ const browser = await launch({
|
|
|
75
75
|
args: ['--window-size=1920,1080'],
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
-
//
|
|
78
|
+
// With timezone and locale (sets --timezone and --lang binary flags)
|
|
79
|
+
const browser = await launch({
|
|
80
|
+
timezone: 'America/New_York',
|
|
81
|
+
locale: 'en-US',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Auto-detect timezone/locale from proxy IP (requires: npm install mmdb-lib)
|
|
85
|
+
const browser = await launch({
|
|
86
|
+
proxy: 'http://proxy:8080',
|
|
87
|
+
geoip: true,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Browser + context in one call (timezone/locale set both binary flags AND context)
|
|
79
91
|
const context = await launchContext({
|
|
80
92
|
userAgent: 'Custom UA',
|
|
81
93
|
viewport: { width: 1920, height: 1080 },
|
|
@@ -84,6 +96,27 @@ const context = await launchContext({
|
|
|
84
96
|
});
|
|
85
97
|
```
|
|
86
98
|
|
|
99
|
+
### Auto Timezone/Locale from Proxy IP
|
|
100
|
+
|
|
101
|
+
When using a proxy, antibot systems check that your browser's timezone and locale match the proxy's location. Install `mmdb-lib` to enable auto-detection from an offline GeoIP database (~70 MB, downloaded on first use):
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install mmdb-lib
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// Auto-detect — timezone and locale set from proxy's IP geolocation
|
|
109
|
+
const browser = await launch({ proxy: 'http://proxy:8080', geoip: true });
|
|
110
|
+
|
|
111
|
+
// Works with launchContext too
|
|
112
|
+
const context = await launchContext({ proxy: 'http://proxy:8080', geoip: true });
|
|
113
|
+
|
|
114
|
+
// Explicit values always win over auto-detection
|
|
115
|
+
const browser = await launch({ proxy: 'http://proxy:8080', geoip: true, timezone: 'Europe/London' });
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> **Note:** For rotating residential proxies, the DNS-resolved IP may differ from the exit IP. Pass explicit `timezone`/`locale` in those cases.
|
|
119
|
+
|
|
87
120
|
### Utilities
|
|
88
121
|
|
|
89
122
|
```javascript
|
package/dist/geoip.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GeoIP-based timezone and locale detection from proxy IP.
|
|
3
|
+
*
|
|
4
|
+
* Optional feature — requires `mmdb-lib` package:
|
|
5
|
+
* npm install mmdb-lib
|
|
6
|
+
*
|
|
7
|
+
* Downloads GeoLite2-City.mmdb (~70 MB) on first use,
|
|
8
|
+
* caches in `~/.cloakbrowser/geoip/`.
|
|
9
|
+
*/
|
|
10
|
+
/** Country ISO code → BCP 47 locale (covers ~90% of proxy traffic). */
|
|
11
|
+
export declare const COUNTRY_LOCALE_MAP: Record<string, string>;
|
|
12
|
+
export interface GeoResult {
|
|
13
|
+
timezone: string | null;
|
|
14
|
+
locale: string | null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve timezone and locale from a proxy's IP address.
|
|
18
|
+
* Returns `{ timezone, locale }` — either may be null on failure.
|
|
19
|
+
* Never throws.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveProxyGeo(proxyUrl: string): Promise<GeoResult>;
|
|
22
|
+
/** @internal Exported for testing. */
|
|
23
|
+
export declare function resolveProxyIp(proxyUrl: string): Promise<string | null>;
|
|
24
|
+
//# sourceMappingURL=geoip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geoip.d.ts","sourceRoot":"","sources":["../src/geoip.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,uEAAuE;AACvE,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAerD,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,CAAC,CA+BpB;AAMD,sCAAsC;AACtC,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAexB"}
|
package/dist/geoip.js
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GeoIP-based timezone and locale detection from proxy IP.
|
|
3
|
+
*
|
|
4
|
+
* Optional feature — requires `mmdb-lib` package:
|
|
5
|
+
* npm install mmdb-lib
|
|
6
|
+
*
|
|
7
|
+
* Downloads GeoLite2-City.mmdb (~70 MB) on first use,
|
|
8
|
+
* caches in `~/.cloakbrowser/geoip/`.
|
|
9
|
+
*/
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import path from "node:path";
|
|
12
|
+
import { createWriteStream } from "node:fs";
|
|
13
|
+
import dns from "node:dns/promises";
|
|
14
|
+
import net from "node:net";
|
|
15
|
+
import { getCacheDir } from "./config.js";
|
|
16
|
+
// P3TERX mirror of MaxMind GeoLite2-City — no license key needed
|
|
17
|
+
const GEOIP_DB_URL = "https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb";
|
|
18
|
+
const GEOIP_DB_FILENAME = "GeoLite2-City.mmdb";
|
|
19
|
+
const GEOIP_UPDATE_INTERVAL_MS = 30 * 86_400_000; // 30 days
|
|
20
|
+
/** Country ISO code → BCP 47 locale (covers ~90% of proxy traffic). */
|
|
21
|
+
export const COUNTRY_LOCALE_MAP = {
|
|
22
|
+
US: "en-US", GB: "en-GB", AU: "en-AU", CA: "en-CA", NZ: "en-NZ",
|
|
23
|
+
IE: "en-IE", ZA: "en-ZA", SG: "en-SG",
|
|
24
|
+
DE: "de-DE", AT: "de-AT", CH: "de-CH",
|
|
25
|
+
FR: "fr-FR", BE: "fr-BE",
|
|
26
|
+
ES: "es-ES", MX: "es-MX", AR: "es-AR", CO: "es-CO", CL: "es-CL",
|
|
27
|
+
BR: "pt-BR", PT: "pt-PT",
|
|
28
|
+
IT: "it-IT", NL: "nl-NL",
|
|
29
|
+
JP: "ja-JP", KR: "ko-KR", CN: "zh-CN", TW: "zh-TW", HK: "zh-HK",
|
|
30
|
+
RU: "ru-RU", UA: "uk-UA", PL: "pl-PL", CZ: "cs-CZ", RO: "ro-RO",
|
|
31
|
+
IL: "he-IL", TR: "tr-TR", SA: "ar-SA", AE: "ar-AE", EG: "ar-EG",
|
|
32
|
+
IN: "hi-IN", ID: "id-ID", PH: "en-PH",
|
|
33
|
+
TH: "th-TH", VN: "vi-VN", MY: "ms-MY",
|
|
34
|
+
SE: "sv-SE", NO: "nb-NO", DK: "da-DK", FI: "fi-FI",
|
|
35
|
+
GR: "el-GR", HU: "hu-HU", BG: "bg-BG",
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Resolve timezone and locale from a proxy's IP address.
|
|
39
|
+
* Returns `{ timezone, locale }` — either may be null on failure.
|
|
40
|
+
* Never throws.
|
|
41
|
+
*/
|
|
42
|
+
export async function resolveProxyGeo(proxyUrl) {
|
|
43
|
+
let Reader;
|
|
44
|
+
try {
|
|
45
|
+
const mmdb = await import("mmdb-lib");
|
|
46
|
+
Reader = mmdb.default?.Reader ?? mmdb.Reader;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new Error("mmdb-lib is required for geoip: true. Install it with:\n npm install mmdb-lib");
|
|
50
|
+
}
|
|
51
|
+
const dbPath = await ensureGeoipDb();
|
|
52
|
+
if (!dbPath)
|
|
53
|
+
return { timezone: null, locale: null };
|
|
54
|
+
// Exit IP (through proxy) is most accurate — gateway DNS may differ from exit
|
|
55
|
+
let ip = await resolveExitIp(proxyUrl);
|
|
56
|
+
if (!ip)
|
|
57
|
+
ip = await resolveProxyIp(proxyUrl);
|
|
58
|
+
if (!ip)
|
|
59
|
+
return { timezone: null, locale: null };
|
|
60
|
+
try {
|
|
61
|
+
const buf = fs.readFileSync(dbPath);
|
|
62
|
+
const reader = new Reader(buf);
|
|
63
|
+
const result = reader.get(ip);
|
|
64
|
+
const timezone = result?.location?.time_zone ?? null;
|
|
65
|
+
const countryCode = result?.country?.iso_code ?? null;
|
|
66
|
+
const locale = countryCode ? (COUNTRY_LOCALE_MAP[countryCode] ?? null) : null;
|
|
67
|
+
return { timezone, locale };
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { timezone: null, locale: null };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Proxy IP resolution
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
/** @internal Exported for testing. */
|
|
77
|
+
export async function resolveProxyIp(proxyUrl) {
|
|
78
|
+
try {
|
|
79
|
+
const url = new URL(proxyUrl);
|
|
80
|
+
const hostname = url.hostname;
|
|
81
|
+
if (!hostname)
|
|
82
|
+
return null;
|
|
83
|
+
// Already a literal IP?
|
|
84
|
+
if (net.isIP(hostname))
|
|
85
|
+
return hostname;
|
|
86
|
+
// DNS resolve
|
|
87
|
+
const { address } = await dns.lookup(hostname);
|
|
88
|
+
return address;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function isPrivateIp(ip) {
|
|
95
|
+
// Quick check for common private ranges
|
|
96
|
+
if (ip.startsWith("10.") || ip.startsWith("127.") || ip === "::1")
|
|
97
|
+
return true;
|
|
98
|
+
if (ip.startsWith("172.")) {
|
|
99
|
+
const second = parseInt(ip.split(".")[1], 10);
|
|
100
|
+
if (second >= 16 && second <= 31)
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
if (ip.startsWith("192.168."))
|
|
104
|
+
return true;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const IP_ECHO_URLS = [
|
|
108
|
+
"https://api.ipify.org",
|
|
109
|
+
"https://checkip.amazonaws.com",
|
|
110
|
+
"https://ifconfig.me/ip",
|
|
111
|
+
];
|
|
112
|
+
async function resolveExitIp(proxyUrl) {
|
|
113
|
+
// Node.js fetch doesn't support proxy natively — use a CONNECT tunnel via http
|
|
114
|
+
// For simplicity, use a direct HTTP request to a plain-text IP echo service
|
|
115
|
+
// through the proxy using Node's http module
|
|
116
|
+
try {
|
|
117
|
+
const { default: http } = await import("node:http");
|
|
118
|
+
const { default: https } = await import("node:https");
|
|
119
|
+
const proxyUrlObj = new URL(proxyUrl);
|
|
120
|
+
for (const echoUrl of IP_ECHO_URLS) {
|
|
121
|
+
try {
|
|
122
|
+
const ip = await new Promise((resolve, reject) => {
|
|
123
|
+
const targetUrl = new URL(echoUrl);
|
|
124
|
+
const connectReq = http.request({
|
|
125
|
+
host: proxyUrlObj.hostname,
|
|
126
|
+
port: parseInt(proxyUrlObj.port || "80", 10),
|
|
127
|
+
method: "CONNECT",
|
|
128
|
+
path: `${targetUrl.hostname}:443`,
|
|
129
|
+
headers: proxyUrlObj.username
|
|
130
|
+
? {
|
|
131
|
+
"Proxy-Authorization": "Basic " +
|
|
132
|
+
Buffer.from(`${decodeURIComponent(proxyUrlObj.username)}:${decodeURIComponent(proxyUrlObj.password || "")}`).toString("base64"),
|
|
133
|
+
}
|
|
134
|
+
: {},
|
|
135
|
+
timeout: 10_000,
|
|
136
|
+
});
|
|
137
|
+
connectReq.on("connect", (_res, socket) => {
|
|
138
|
+
const req = https.request(echoUrl, { socket, timeout: 5_000 }, (res) => {
|
|
139
|
+
let data = "";
|
|
140
|
+
res.on("data", (chunk) => (data += chunk.toString()));
|
|
141
|
+
res.on("end", () => {
|
|
142
|
+
const ip = data.trim();
|
|
143
|
+
resolve(net.isIP(ip) ? ip : null);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
req.on("error", () => resolve(null));
|
|
147
|
+
req.end();
|
|
148
|
+
});
|
|
149
|
+
connectReq.on("error", () => resolve(null));
|
|
150
|
+
connectReq.on("timeout", () => {
|
|
151
|
+
connectReq.destroy();
|
|
152
|
+
resolve(null);
|
|
153
|
+
});
|
|
154
|
+
connectReq.end();
|
|
155
|
+
});
|
|
156
|
+
if (ip)
|
|
157
|
+
return ip;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Fallback: couldn't import http modules
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
// ---------------------------------------------------------------------------
|
|
170
|
+
// GeoIP database management
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
function getGeoipDir() {
|
|
173
|
+
return path.join(getCacheDir(), "geoip");
|
|
174
|
+
}
|
|
175
|
+
async function ensureGeoipDb() {
|
|
176
|
+
const dir = getGeoipDir();
|
|
177
|
+
const dbPath = path.join(dir, GEOIP_DB_FILENAME);
|
|
178
|
+
if (fs.existsSync(dbPath)) {
|
|
179
|
+
maybeTriggerUpdate(dbPath);
|
|
180
|
+
return dbPath;
|
|
181
|
+
}
|
|
182
|
+
try {
|
|
183
|
+
await downloadGeoipDb(dbPath);
|
|
184
|
+
return dbPath;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function downloadGeoipDb(dest) {
|
|
191
|
+
const dir = path.dirname(dest);
|
|
192
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
193
|
+
console.log("[cloakbrowser] Downloading GeoIP database (~70 MB)…");
|
|
194
|
+
const tmpPath = `${dest}.tmp.${Date.now()}`;
|
|
195
|
+
try {
|
|
196
|
+
const response = await fetch(GEOIP_DB_URL, { redirect: "follow" });
|
|
197
|
+
if (!response.ok || !response.body) {
|
|
198
|
+
throw new Error(`HTTP ${response.status}`);
|
|
199
|
+
}
|
|
200
|
+
const fileStream = createWriteStream(tmpPath);
|
|
201
|
+
const reader = response.body.getReader();
|
|
202
|
+
for (;;) {
|
|
203
|
+
const { done, value } = await reader.read();
|
|
204
|
+
if (done)
|
|
205
|
+
break;
|
|
206
|
+
fileStream.write(value);
|
|
207
|
+
}
|
|
208
|
+
await new Promise((resolve, reject) => {
|
|
209
|
+
fileStream.end(() => resolve());
|
|
210
|
+
fileStream.on("error", reject);
|
|
211
|
+
});
|
|
212
|
+
fs.renameSync(tmpPath, dest);
|
|
213
|
+
console.log(`[cloakbrowser] GeoIP database ready: ${dest}`);
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
if (fs.existsSync(tmpPath))
|
|
217
|
+
fs.unlinkSync(tmpPath);
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function maybeTriggerUpdate(dbPath) {
|
|
222
|
+
try {
|
|
223
|
+
const age = Date.now() - fs.statSync(dbPath).mtimeMs;
|
|
224
|
+
if (age < GEOIP_UPDATE_INTERVAL_MS)
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
// Fire-and-forget background update
|
|
231
|
+
downloadGeoipDb(dbPath).catch(() => { });
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=geoip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geoip.js","sourceRoot":"","sources":["../src/geoip.ts"],"names":[],"mappings":"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"}
|
package/dist/playwright.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKtE;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"playwright.d.ts","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKtE;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CA0BzB"}
|
package/dist/playwright.js
CHANGED
|
@@ -21,7 +21,8 @@ import { parseProxyUrl } from "./proxy.js";
|
|
|
21
21
|
export async function launch(options = {}) {
|
|
22
22
|
const { chromium } = await import("playwright-core");
|
|
23
23
|
const binaryPath = process.env.CLOAKBROWSER_BINARY_PATH || (await ensureBinary());
|
|
24
|
-
const
|
|
24
|
+
const resolved = await maybeResolveGeoip(options);
|
|
25
|
+
const args = buildArgs({ ...options, ...resolved });
|
|
25
26
|
const browser = await chromium.launch({
|
|
26
27
|
executablePath: binaryPath,
|
|
27
28
|
headless: options.headless ?? true,
|
|
@@ -49,14 +50,16 @@ export async function launch(options = {}) {
|
|
|
49
50
|
* ```
|
|
50
51
|
*/
|
|
51
52
|
export async function launchContext(options = {}) {
|
|
52
|
-
|
|
53
|
+
// Resolve geoip BEFORE launch() to avoid double-resolution
|
|
54
|
+
const resolved = await maybeResolveGeoip(options);
|
|
55
|
+
const browser = await launch({ ...options, ...resolved, geoip: false });
|
|
53
56
|
let context;
|
|
54
57
|
try {
|
|
55
58
|
context = await browser.newContext({
|
|
56
59
|
...(options.userAgent ? { userAgent: options.userAgent } : {}),
|
|
57
60
|
...(options.viewport ? { viewport: options.viewport } : {}),
|
|
58
|
-
...(
|
|
59
|
-
...(
|
|
61
|
+
...(resolved.locale ? { locale: resolved.locale } : {}),
|
|
62
|
+
...(resolved.timezone ? { timezoneId: resolved.timezone } : {}),
|
|
60
63
|
});
|
|
61
64
|
}
|
|
62
65
|
catch (err) {
|
|
@@ -74,6 +77,18 @@ export async function launchContext(options = {}) {
|
|
|
74
77
|
// ---------------------------------------------------------------------------
|
|
75
78
|
// Internal
|
|
76
79
|
// ---------------------------------------------------------------------------
|
|
80
|
+
async function maybeResolveGeoip(options) {
|
|
81
|
+
if (!options.geoip || !options.proxy)
|
|
82
|
+
return { timezone: options.timezone, locale: options.locale };
|
|
83
|
+
if (options.timezone && options.locale)
|
|
84
|
+
return { timezone: options.timezone, locale: options.locale };
|
|
85
|
+
const { resolveProxyGeo } = await import("./geoip.js");
|
|
86
|
+
const { timezone: geoTz, locale: geoLocale } = await resolveProxyGeo(options.proxy);
|
|
87
|
+
return {
|
|
88
|
+
timezone: options.timezone ?? geoTz ?? undefined,
|
|
89
|
+
locale: options.locale ?? geoLocale ?? undefined,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
77
92
|
function buildArgs(options) {
|
|
78
93
|
const args = [];
|
|
79
94
|
if (options.stealthArgs !== false) {
|
|
@@ -82,6 +97,13 @@ function buildArgs(options) {
|
|
|
82
97
|
if (options.args) {
|
|
83
98
|
args.push(...options.args);
|
|
84
99
|
}
|
|
100
|
+
// Timezone/locale flags — always inject when set
|
|
101
|
+
if (options.timezone) {
|
|
102
|
+
args.push(`--timezone=${options.timezone}`);
|
|
103
|
+
}
|
|
104
|
+
if (options.locale) {
|
|
105
|
+
args.push(`--lang=${options.locale}`);
|
|
106
|
+
}
|
|
85
107
|
return args;
|
|
86
108
|
}
|
|
87
109
|
//# sourceMappingURL=playwright.js.map
|
package/dist/playwright.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,UAAyB,EAAE;IACtD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAErD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;IAClF,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"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"}
|
package/dist/puppeteer.d.ts.map
CHANGED
|
@@ -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;AAKhD;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
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;AAKhD;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuC1E"}
|
package/dist/puppeteer.js
CHANGED
|
@@ -21,7 +21,8 @@ import { parseProxyUrl } from "./proxy.js";
|
|
|
21
21
|
export async function launch(options = {}) {
|
|
22
22
|
const puppeteer = await import("puppeteer-core");
|
|
23
23
|
const binaryPath = process.env.CLOAKBROWSER_BINARY_PATH || (await ensureBinary());
|
|
24
|
-
const
|
|
24
|
+
const resolved = await maybeResolveGeoip(options);
|
|
25
|
+
const args = buildArgs({ ...options, ...resolved });
|
|
25
26
|
// Puppeteer handles proxy via CLI args, not a separate option.
|
|
26
27
|
// Chromium's --proxy-server does NOT support inline credentials,
|
|
27
28
|
// so we strip them and use page.authenticate() instead.
|
|
@@ -55,6 +56,18 @@ export async function launch(options = {}) {
|
|
|
55
56
|
// ---------------------------------------------------------------------------
|
|
56
57
|
// Internal
|
|
57
58
|
// ---------------------------------------------------------------------------
|
|
59
|
+
async function maybeResolveGeoip(options) {
|
|
60
|
+
if (!options.geoip || !options.proxy)
|
|
61
|
+
return { timezone: options.timezone, locale: options.locale };
|
|
62
|
+
if (options.timezone && options.locale)
|
|
63
|
+
return { timezone: options.timezone, locale: options.locale };
|
|
64
|
+
const { resolveProxyGeo } = await import("./geoip.js");
|
|
65
|
+
const { timezone: geoTz, locale: geoLocale } = await resolveProxyGeo(options.proxy);
|
|
66
|
+
return {
|
|
67
|
+
timezone: options.timezone ?? geoTz ?? undefined,
|
|
68
|
+
locale: options.locale ?? geoLocale ?? undefined,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
58
71
|
function buildArgs(options) {
|
|
59
72
|
const args = [];
|
|
60
73
|
if (options.stealthArgs !== false) {
|
|
@@ -63,6 +76,12 @@ function buildArgs(options) {
|
|
|
63
76
|
if (options.args) {
|
|
64
77
|
args.push(...options.args);
|
|
65
78
|
}
|
|
79
|
+
if (options.timezone) {
|
|
80
|
+
args.push(`--timezone=${options.timezone}`);
|
|
81
|
+
}
|
|
82
|
+
if (options.locale) {
|
|
83
|
+
args.push(`--lang=${options.locale}`);
|
|
84
|
+
}
|
|
66
85
|
return args;
|
|
67
86
|
}
|
|
68
87
|
//# sourceMappingURL=puppeteer.js.map
|
package/dist/puppeteer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"puppeteer.js","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;;;;;GAYG;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,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"puppeteer.js","sourceRoot":"","sources":["../src/puppeteer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ export interface LaunchOptions {
|
|
|
10
10
|
args?: string[];
|
|
11
11
|
/** Include default stealth fingerprint args (default: true). Set false to use custom --fingerprint flags. */
|
|
12
12
|
stealthArgs?: boolean;
|
|
13
|
+
/** IANA timezone, e.g. "America/New_York". Sets --timezone binary flag. */
|
|
14
|
+
timezone?: string;
|
|
15
|
+
/** BCP 47 locale, e.g. "en-US". Sets --lang binary flag. */
|
|
16
|
+
locale?: string;
|
|
17
|
+
/** Auto-detect timezone/locale from proxy IP (requires: npm install mmdb-lib). */
|
|
18
|
+
geoip?: boolean;
|
|
13
19
|
/** Raw options passed directly to playwright/puppeteer launch(). */
|
|
14
20
|
launchOptions?: Record<string, unknown>;
|
|
15
21
|
}
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,6GAA6G;IAC7G,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,6GAA6G;IAC7G,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloakbrowser",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
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",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"node": ">=18.0.0"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
+
"mmdb-lib": ">=2.0.0",
|
|
46
47
|
"playwright-core": ">=1.40.0",
|
|
47
48
|
"puppeteer-core": ">=21.0.0"
|
|
48
49
|
},
|
|
@@ -52,6 +53,9 @@
|
|
|
52
53
|
},
|
|
53
54
|
"puppeteer-core": {
|
|
54
55
|
"optional": true
|
|
56
|
+
},
|
|
57
|
+
"mmdb-lib": {
|
|
58
|
+
"optional": true
|
|
55
59
|
}
|
|
56
60
|
},
|
|
57
61
|
"dependencies": {
|
|
@@ -59,6 +63,7 @@
|
|
|
59
63
|
},
|
|
60
64
|
"devDependencies": {
|
|
61
65
|
"@types/node": "^20.10.0",
|
|
66
|
+
"mmdb-lib": "^3.0.2",
|
|
62
67
|
"playwright-core": "^1.40.0",
|
|
63
68
|
"puppeteer-core": "^21.0.0",
|
|
64
69
|
"typescript": "^5.3.0",
|