cloakbrowser 0.1.0
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/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/download.d.ts +16 -0
- package/dist/download.d.ts.map +1 -0
- package/dist/download.js +191 -0
- package/dist/download.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/playwright.d.ts +38 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +86 -0
- package/dist/playwright.js.map +1 -0
- package/dist/puppeteer.d.ts +21 -0
- package/dist/puppeteer.d.ts.map +1 -0
- package/dist/puppeteer.js +50 -0
- package/dist/puppeteer.js.map +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth configuration and platform detection for cloakbrowser.
|
|
3
|
+
* Mirrors Python cloakbrowser/config.py.
|
|
4
|
+
*/
|
|
5
|
+
export declare const CHROMIUM_VERSION = "142.0.7444.175";
|
|
6
|
+
export declare function getPlatformTag(): string;
|
|
7
|
+
export declare function getCacheDir(): string;
|
|
8
|
+
export declare function getBinaryDir(): string;
|
|
9
|
+
export declare function getBinaryPath(): string;
|
|
10
|
+
export declare function getDownloadUrl(): string;
|
|
11
|
+
export declare function getLocalBinaryOverride(): string | undefined;
|
|
12
|
+
export declare function getDefaultStealthArgs(): string[];
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAYjD,wBAAgB,cAAc,IAAI,MAAM,CAkBvC;AAKD,wBAAgB,WAAW,IAAI,MAAM,CAIpC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AASD,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAKD,wBAAgB,sBAAsB,IAAI,MAAM,GAAG,SAAS,CAE3D;AAKD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAWhD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stealth configuration and platform detection for cloakbrowser.
|
|
3
|
+
* Mirrors Python cloakbrowser/config.py.
|
|
4
|
+
*/
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Chromium version shipped with this release
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
export const CHROMIUM_VERSION = "142.0.7444.175";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Platform detection
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const SUPPORTED_PLATFORMS = {
|
|
15
|
+
"linux-x64": "linux-x64",
|
|
16
|
+
"linux-arm64": "linux-arm64",
|
|
17
|
+
"darwin-arm64": "darwin-arm64",
|
|
18
|
+
"darwin-x64": "darwin-x64",
|
|
19
|
+
};
|
|
20
|
+
export function getPlatformTag() {
|
|
21
|
+
const platform = process.platform;
|
|
22
|
+
const arch = process.arch;
|
|
23
|
+
// Map Node.js platform/arch to our tag format
|
|
24
|
+
let key;
|
|
25
|
+
if (platform === "linux" && arch === "x64")
|
|
26
|
+
key = "linux-x64";
|
|
27
|
+
else if (platform === "linux" && arch === "arm64")
|
|
28
|
+
key = "linux-arm64";
|
|
29
|
+
else if (platform === "darwin" && arch === "arm64")
|
|
30
|
+
key = "darwin-arm64";
|
|
31
|
+
else if (platform === "darwin" && arch === "x64")
|
|
32
|
+
key = "darwin-x64";
|
|
33
|
+
else {
|
|
34
|
+
const supported = Object.values(SUPPORTED_PLATFORMS).join(", ");
|
|
35
|
+
throw new Error(`Unsupported platform: ${platform} ${arch}. Supported: ${supported}`);
|
|
36
|
+
}
|
|
37
|
+
return SUPPORTED_PLATFORMS[key];
|
|
38
|
+
}
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
// Binary cache paths
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
export function getCacheDir() {
|
|
43
|
+
const custom = process.env.CLOAKBROWSER_CACHE_DIR;
|
|
44
|
+
if (custom)
|
|
45
|
+
return custom;
|
|
46
|
+
return path.join(os.homedir(), ".cloakbrowser");
|
|
47
|
+
}
|
|
48
|
+
export function getBinaryDir() {
|
|
49
|
+
return path.join(getCacheDir(), `chromium-${CHROMIUM_VERSION}`);
|
|
50
|
+
}
|
|
51
|
+
export function getBinaryPath() {
|
|
52
|
+
const binaryDir = getBinaryDir();
|
|
53
|
+
if (process.platform === "darwin") {
|
|
54
|
+
return path.join(binaryDir, "Chromium.app", "Contents", "MacOS", "Chromium");
|
|
55
|
+
}
|
|
56
|
+
return path.join(binaryDir, "chrome");
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Download URL
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
const DOWNLOAD_BASE_URL = process.env.CLOAKBROWSER_DOWNLOAD_URL ||
|
|
62
|
+
"https://github.com/CloakHQ/chromium-stealth-builds/releases/download";
|
|
63
|
+
export function getDownloadUrl() {
|
|
64
|
+
const tag = getPlatformTag();
|
|
65
|
+
return `${DOWNLOAD_BASE_URL}/v${CHROMIUM_VERSION}/cloakbrowser-${tag}.tar.gz`;
|
|
66
|
+
}
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Local binary override
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
export function getLocalBinaryOverride() {
|
|
71
|
+
return process.env.CLOAKBROWSER_BINARY_PATH || undefined;
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Default stealth arguments
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
export function getDefaultStealthArgs() {
|
|
77
|
+
const seed = Math.floor(Math.random() * 90000) + 10000; // 10000-99999
|
|
78
|
+
return [
|
|
79
|
+
"--no-sandbox",
|
|
80
|
+
"--disable-blink-features=AutomationControlled",
|
|
81
|
+
`--fingerprint=${seed}`,
|
|
82
|
+
"--fingerprint-platform=windows",
|
|
83
|
+
"--fingerprint-hardware-concurrency=8",
|
|
84
|
+
"--fingerprint-gpu-vendor=NVIDIA Corporation",
|
|
85
|
+
"--fingerprint-gpu-renderer=NVIDIA GeForce RTX 3070",
|
|
86
|
+
];
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary download and cache management for cloakbrowser.
|
|
3
|
+
* Downloads the patched Chromium binary on first use, caches it locally.
|
|
4
|
+
* Mirrors Python cloakbrowser/download.py.
|
|
5
|
+
*/
|
|
6
|
+
import type { BinaryInfo } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Ensure the stealth Chromium binary is available. Download if needed.
|
|
9
|
+
* Returns the path to the chrome executable.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureBinary(): Promise<string>;
|
|
12
|
+
/** Remove all cached binaries. Forces re-download on next launch. */
|
|
13
|
+
export declare function clearCache(): void;
|
|
14
|
+
/** Return info about the current binary installation. */
|
|
15
|
+
export declare function binaryInfo(): BinaryInfo;
|
|
16
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAiB7C;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAkCpD;AAED,qEAAqE;AACrE,wBAAgB,UAAU,IAAI,IAAI,CAMjC;AAED,yDAAyD;AACzD,wBAAgB,UAAU,IAAI,UAAU,CAUvC"}
|
package/dist/download.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binary download and cache management for cloakbrowser.
|
|
3
|
+
* Downloads the patched Chromium binary on first use, caches it locally.
|
|
4
|
+
* Mirrors Python cloakbrowser/download.py.
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import { createWriteStream } from "node:fs";
|
|
9
|
+
import { extract as tarExtract } from "tar";
|
|
10
|
+
import { CHROMIUM_VERSION, getBinaryDir, getBinaryPath, getDownloadUrl, getLocalBinaryOverride, getPlatformTag, getCacheDir, } from "./config.js";
|
|
11
|
+
const DOWNLOAD_TIMEOUT_MS = 600_000; // 10 minutes
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Public API
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/**
|
|
16
|
+
* Ensure the stealth Chromium binary is available. Download if needed.
|
|
17
|
+
* Returns the path to the chrome executable.
|
|
18
|
+
*/
|
|
19
|
+
export async function ensureBinary() {
|
|
20
|
+
// Check for local override
|
|
21
|
+
const localOverride = getLocalBinaryOverride();
|
|
22
|
+
if (localOverride) {
|
|
23
|
+
if (!fs.existsSync(localOverride)) {
|
|
24
|
+
throw new Error(`CLOAKBROWSER_BINARY_PATH set to '${localOverride}' but file does not exist`);
|
|
25
|
+
}
|
|
26
|
+
console.log(`[cloakbrowser] Using local binary override: ${localOverride}`);
|
|
27
|
+
return localOverride;
|
|
28
|
+
}
|
|
29
|
+
// Check if binary is cached
|
|
30
|
+
const binaryPath = getBinaryPath();
|
|
31
|
+
if (fs.existsSync(binaryPath) && isExecutable(binaryPath)) {
|
|
32
|
+
return binaryPath;
|
|
33
|
+
}
|
|
34
|
+
// Download
|
|
35
|
+
console.log(`[cloakbrowser] Stealth Chromium ${CHROMIUM_VERSION} not found. Downloading for ${getPlatformTag()}...`);
|
|
36
|
+
await downloadAndExtract();
|
|
37
|
+
if (!fs.existsSync(binaryPath)) {
|
|
38
|
+
throw new Error(`Download completed but binary not found at expected path: ${binaryPath}. ` +
|
|
39
|
+
`This may indicate a packaging issue. Please report at ` +
|
|
40
|
+
`https://github.com/CloakHQ/cloakbrowser/issues`);
|
|
41
|
+
}
|
|
42
|
+
return binaryPath;
|
|
43
|
+
}
|
|
44
|
+
/** Remove all cached binaries. Forces re-download on next launch. */
|
|
45
|
+
export function clearCache() {
|
|
46
|
+
const cacheDir = getCacheDir();
|
|
47
|
+
if (fs.existsSync(cacheDir)) {
|
|
48
|
+
fs.rmSync(cacheDir, { recursive: true, force: true });
|
|
49
|
+
console.log(`[cloakbrowser] Cache cleared: ${cacheDir}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/** Return info about the current binary installation. */
|
|
53
|
+
export function binaryInfo() {
|
|
54
|
+
const binaryPath = getBinaryPath();
|
|
55
|
+
return {
|
|
56
|
+
version: CHROMIUM_VERSION,
|
|
57
|
+
platform: getPlatformTag(),
|
|
58
|
+
binaryPath,
|
|
59
|
+
installed: fs.existsSync(binaryPath),
|
|
60
|
+
cacheDir: getBinaryDir(),
|
|
61
|
+
downloadUrl: getDownloadUrl(),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Internal helpers
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
async function downloadAndExtract() {
|
|
68
|
+
const url = getDownloadUrl();
|
|
69
|
+
const binaryDir = getBinaryDir();
|
|
70
|
+
// Create cache dir
|
|
71
|
+
fs.mkdirSync(path.dirname(binaryDir), { recursive: true });
|
|
72
|
+
// Download to temp file (atomic — no partial downloads in cache)
|
|
73
|
+
const tmpPath = path.join(path.dirname(binaryDir), `_download_${Date.now()}.tar.gz`);
|
|
74
|
+
try {
|
|
75
|
+
await downloadFile(url, tmpPath);
|
|
76
|
+
await extractArchive(tmpPath, binaryDir);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
// Clean up temp file
|
|
80
|
+
if (fs.existsSync(tmpPath)) {
|
|
81
|
+
fs.unlinkSync(tmpPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function downloadFile(url, dest) {
|
|
86
|
+
console.log(`[cloakbrowser] Downloading from ${url}`);
|
|
87
|
+
const controller = new AbortController();
|
|
88
|
+
const timeout = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
|
|
89
|
+
try {
|
|
90
|
+
const response = await fetch(url, {
|
|
91
|
+
signal: controller.signal,
|
|
92
|
+
redirect: "follow",
|
|
93
|
+
});
|
|
94
|
+
if (!response.ok) {
|
|
95
|
+
throw new Error(`Download failed: HTTP ${response.status} ${response.statusText}`);
|
|
96
|
+
}
|
|
97
|
+
if (!response.body) {
|
|
98
|
+
throw new Error("Download failed: empty response body");
|
|
99
|
+
}
|
|
100
|
+
const total = Number(response.headers.get("content-length") || 0);
|
|
101
|
+
let downloaded = 0;
|
|
102
|
+
let lastLoggedPct = -1;
|
|
103
|
+
const fileStream = createWriteStream(dest);
|
|
104
|
+
const reader = response.body.getReader();
|
|
105
|
+
// Stream chunks to file with progress logging
|
|
106
|
+
while (true) {
|
|
107
|
+
const { done, value } = await reader.read();
|
|
108
|
+
if (done)
|
|
109
|
+
break;
|
|
110
|
+
fileStream.write(value);
|
|
111
|
+
downloaded += value.length;
|
|
112
|
+
if (total > 0) {
|
|
113
|
+
const pct = Math.floor((downloaded / total) * 100);
|
|
114
|
+
if (pct >= lastLoggedPct + 10) {
|
|
115
|
+
lastLoggedPct = pct;
|
|
116
|
+
const dlMB = Math.floor(downloaded / (1024 * 1024));
|
|
117
|
+
const totalMB = Math.floor(total / (1024 * 1024));
|
|
118
|
+
console.log(`[cloakbrowser] Download progress: ${pct}% (${dlMB}/${totalMB} MB)`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Wait for file stream to finish
|
|
123
|
+
await new Promise((resolve, reject) => {
|
|
124
|
+
fileStream.end(() => resolve());
|
|
125
|
+
fileStream.on("error", reject);
|
|
126
|
+
});
|
|
127
|
+
const sizeMB = Math.floor(fs.statSync(dest).size / (1024 * 1024));
|
|
128
|
+
console.log(`[cloakbrowser] Download complete: ${sizeMB} MB`);
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
clearTimeout(timeout);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async function extractArchive(archivePath, destDir) {
|
|
135
|
+
console.log(`[cloakbrowser] Extracting to ${destDir}`);
|
|
136
|
+
// Clean existing dir if partial download existed
|
|
137
|
+
if (fs.existsSync(destDir)) {
|
|
138
|
+
fs.rmSync(destDir, { recursive: true, force: true });
|
|
139
|
+
}
|
|
140
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
141
|
+
// Extract with tar — the 'tar' package handles symlink/traversal safety
|
|
142
|
+
await tarExtract({
|
|
143
|
+
file: archivePath,
|
|
144
|
+
cwd: destDir,
|
|
145
|
+
// Security: strip leading path components and reject absolute paths
|
|
146
|
+
strip: 0,
|
|
147
|
+
filter: (entryPath) => {
|
|
148
|
+
// Reject absolute paths and path traversal
|
|
149
|
+
if (path.isAbsolute(entryPath) || entryPath.includes("..")) {
|
|
150
|
+
console.warn(`[cloakbrowser] Skipping suspicious archive entry: ${entryPath}`);
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
// Flatten single subdirectory if needed
|
|
157
|
+
flattenSingleSubdir(destDir);
|
|
158
|
+
// Make binary executable
|
|
159
|
+
const binaryPath = getBinaryPath();
|
|
160
|
+
if (fs.existsSync(binaryPath)) {
|
|
161
|
+
fs.chmodSync(binaryPath, 0o755);
|
|
162
|
+
console.log(`[cloakbrowser] Binary ready: ${binaryPath}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* If extraction created a single subdirectory, move its contents up.
|
|
167
|
+
* Many tarballs wrap files in a top-level directory.
|
|
168
|
+
*/
|
|
169
|
+
function flattenSingleSubdir(destDir) {
|
|
170
|
+
const entries = fs.readdirSync(destDir);
|
|
171
|
+
if (entries.length === 1) {
|
|
172
|
+
const subdir = path.join(destDir, entries[0]);
|
|
173
|
+
if (fs.statSync(subdir).isDirectory()) {
|
|
174
|
+
const children = fs.readdirSync(subdir);
|
|
175
|
+
for (const child of children) {
|
|
176
|
+
fs.renameSync(path.join(subdir, child), path.join(destDir, child));
|
|
177
|
+
}
|
|
178
|
+
fs.rmdirSync(subdir);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function isExecutable(filePath) {
|
|
183
|
+
try {
|
|
184
|
+
fs.accessSync(filePath, fs.constants.X_OK);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloakBrowser — Stealth Chromium for Node.js
|
|
3
|
+
*
|
|
4
|
+
* Default export uses Playwright. For Puppeteer, import from 'cloakbrowser/puppeteer'.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* // Playwright (default)
|
|
9
|
+
* import { launch } from 'cloakbrowser';
|
|
10
|
+
* const browser = await launch();
|
|
11
|
+
*
|
|
12
|
+
* // Puppeteer
|
|
13
|
+
* import { launch } from 'cloakbrowser/puppeteer';
|
|
14
|
+
* const browser = await launch();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export { launch, launchContext } from "./playwright.js";
|
|
18
|
+
export { ensureBinary, clearCache, binaryInfo } from "./download.js";
|
|
19
|
+
export { CHROMIUM_VERSION, getDefaultStealthArgs } from "./config.js";
|
|
20
|
+
export type { LaunchOptions, LaunchContextOptions, BinaryInfo } from "./types.js";
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGxD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGrE,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGtE,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloakBrowser — Stealth Chromium for Node.js
|
|
3
|
+
*
|
|
4
|
+
* Default export uses Playwright. For Puppeteer, import from 'cloakbrowser/puppeteer'.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* // Playwright (default)
|
|
9
|
+
* import { launch } from 'cloakbrowser';
|
|
10
|
+
* const browser = await launch();
|
|
11
|
+
*
|
|
12
|
+
* // Puppeteer
|
|
13
|
+
* import { launch } from 'cloakbrowser/puppeteer';
|
|
14
|
+
* const browser = await launch();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
// Launch functions (Playwright API)
|
|
18
|
+
export { launch, launchContext } from "./playwright.js";
|
|
19
|
+
// Binary management
|
|
20
|
+
export { ensureBinary, clearCache, binaryInfo } from "./download.js";
|
|
21
|
+
// Config
|
|
22
|
+
export { CHROMIUM_VERSION, getDefaultStealthArgs } from "./config.js";
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,oCAAoC;AACpC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAExD,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAErE,SAAS;AACT,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright launch wrapper for cloakbrowser.
|
|
3
|
+
* Mirrors Python cloakbrowser/browser.py.
|
|
4
|
+
*/
|
|
5
|
+
import type { Browser, BrowserContext } from "playwright-core";
|
|
6
|
+
import type { LaunchOptions, LaunchContextOptions } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Launch stealth Chromium browser via Playwright.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { launch } from 'cloakbrowser';
|
|
13
|
+
* const browser = await launch();
|
|
14
|
+
* const page = await browser.newPage();
|
|
15
|
+
* await page.goto('https://bot.incolumitas.com');
|
|
16
|
+
* console.log(await page.title());
|
|
17
|
+
* await browser.close();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function launch(options?: LaunchOptions): Promise<Browser>;
|
|
21
|
+
/**
|
|
22
|
+
* Launch stealth browser and return a BrowserContext with common options pre-set.
|
|
23
|
+
* Closing the context also closes the browser.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { launchContext } from 'cloakbrowser';
|
|
28
|
+
* const context = await launchContext({
|
|
29
|
+
* userAgent: 'Mozilla/5.0...',
|
|
30
|
+
* viewport: { width: 1920, height: 1080 },
|
|
31
|
+
* });
|
|
32
|
+
* const page = await context.newPage();
|
|
33
|
+
* await page.goto('https://example.com');
|
|
34
|
+
* await context.close(); // also closes browser
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function launchContext(options?: LaunchContextOptions): Promise<BrowserContext>;
|
|
38
|
+
//# sourceMappingURL=playwright.d.ts.map
|
|
@@ -0,0 +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;AAItE;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,cAAc,CAAC,CAwBzB"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright launch wrapper for cloakbrowser.
|
|
3
|
+
* Mirrors Python cloakbrowser/browser.py.
|
|
4
|
+
*/
|
|
5
|
+
import { getDefaultStealthArgs } from "./config.js";
|
|
6
|
+
import { ensureBinary } from "./download.js";
|
|
7
|
+
/**
|
|
8
|
+
* Launch stealth Chromium browser via Playwright.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { launch } from 'cloakbrowser';
|
|
13
|
+
* const browser = await launch();
|
|
14
|
+
* const page = await browser.newPage();
|
|
15
|
+
* await page.goto('https://bot.incolumitas.com');
|
|
16
|
+
* console.log(await page.title());
|
|
17
|
+
* await browser.close();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export async function launch(options = {}) {
|
|
21
|
+
const { chromium } = await import("playwright-core");
|
|
22
|
+
const binaryPath = process.env.CLOAKBROWSER_BINARY_PATH || (await ensureBinary());
|
|
23
|
+
const args = buildArgs(options);
|
|
24
|
+
const browser = await chromium.launch({
|
|
25
|
+
executablePath: binaryPath,
|
|
26
|
+
headless: options.headless ?? true,
|
|
27
|
+
args,
|
|
28
|
+
ignoreDefaultArgs: ["--enable-automation"],
|
|
29
|
+
...(options.proxy ? { proxy: { server: options.proxy } } : {}),
|
|
30
|
+
...options.launchOptions,
|
|
31
|
+
});
|
|
32
|
+
return browser;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Launch stealth browser and return a BrowserContext with common options pre-set.
|
|
36
|
+
* Closing the context also closes the browser.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { launchContext } from 'cloakbrowser';
|
|
41
|
+
* const context = await launchContext({
|
|
42
|
+
* userAgent: 'Mozilla/5.0...',
|
|
43
|
+
* viewport: { width: 1920, height: 1080 },
|
|
44
|
+
* });
|
|
45
|
+
* const page = await context.newPage();
|
|
46
|
+
* await page.goto('https://example.com');
|
|
47
|
+
* await context.close(); // also closes browser
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export async function launchContext(options = {}) {
|
|
51
|
+
const browser = await launch(options);
|
|
52
|
+
let context;
|
|
53
|
+
try {
|
|
54
|
+
context = await browser.newContext({
|
|
55
|
+
...(options.userAgent ? { userAgent: options.userAgent } : {}),
|
|
56
|
+
...(options.viewport ? { viewport: options.viewport } : {}),
|
|
57
|
+
...(options.locale ? { locale: options.locale } : {}),
|
|
58
|
+
...(options.timezoneId ? { timezoneId: options.timezoneId } : {}),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
await browser.close();
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
// Patch close() to also close the browser
|
|
66
|
+
const origClose = context.close.bind(context);
|
|
67
|
+
context.close = async () => {
|
|
68
|
+
await origClose();
|
|
69
|
+
await browser.close();
|
|
70
|
+
};
|
|
71
|
+
return context;
|
|
72
|
+
}
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Internal
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
function buildArgs(options) {
|
|
77
|
+
const args = [];
|
|
78
|
+
if (options.stealthArgs !== false) {
|
|
79
|
+
args.push(...getDefaultStealthArgs());
|
|
80
|
+
}
|
|
81
|
+
if (options.args) {
|
|
82
|
+
args.push(...options.args);
|
|
83
|
+
}
|
|
84
|
+
return args;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=playwright.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"playwright.js","sourceRoot":"","sources":["../src/playwright.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Puppeteer launch wrapper for cloakbrowser.
|
|
3
|
+
* Alternative to the Playwright wrapper for users who prefer Puppeteer.
|
|
4
|
+
*/
|
|
5
|
+
import type { Browser } from "puppeteer-core";
|
|
6
|
+
import type { LaunchOptions } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Launch stealth Chromium browser via Puppeteer.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { launch } from 'cloakbrowser/puppeteer';
|
|
13
|
+
* const browser = await launch();
|
|
14
|
+
* const page = await browser.newPage();
|
|
15
|
+
* await page.goto('https://bot.incolumitas.com');
|
|
16
|
+
* console.log(await page.title());
|
|
17
|
+
* await browser.close();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function launch(options?: LaunchOptions): Promise<Browser>;
|
|
21
|
+
//# sourceMappingURL=puppeteer.d.ts.map
|
|
@@ -0,0 +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;AAIhD;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB1E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Puppeteer launch wrapper for cloakbrowser.
|
|
3
|
+
* Alternative to the Playwright wrapper for users who prefer Puppeteer.
|
|
4
|
+
*/
|
|
5
|
+
import { getDefaultStealthArgs } from "./config.js";
|
|
6
|
+
import { ensureBinary } from "./download.js";
|
|
7
|
+
/**
|
|
8
|
+
* Launch stealth Chromium browser via Puppeteer.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { launch } from 'cloakbrowser/puppeteer';
|
|
13
|
+
* const browser = await launch();
|
|
14
|
+
* const page = await browser.newPage();
|
|
15
|
+
* await page.goto('https://bot.incolumitas.com');
|
|
16
|
+
* console.log(await page.title());
|
|
17
|
+
* await browser.close();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export async function launch(options = {}) {
|
|
21
|
+
const puppeteer = await import("puppeteer-core");
|
|
22
|
+
const binaryPath = process.env.CLOAKBROWSER_BINARY_PATH || (await ensureBinary());
|
|
23
|
+
const args = buildArgs(options);
|
|
24
|
+
// Puppeteer handles proxy via CLI args, not a separate option
|
|
25
|
+
if (options.proxy) {
|
|
26
|
+
args.push(`--proxy-server=${options.proxy}`);
|
|
27
|
+
}
|
|
28
|
+
const browser = await puppeteer.default.launch({
|
|
29
|
+
executablePath: binaryPath,
|
|
30
|
+
headless: options.headless ?? true,
|
|
31
|
+
args,
|
|
32
|
+
ignoreDefaultArgs: ["--enable-automation"],
|
|
33
|
+
...options.launchOptions,
|
|
34
|
+
});
|
|
35
|
+
return browser;
|
|
36
|
+
}
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Internal
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
function buildArgs(options) {
|
|
41
|
+
const args = [];
|
|
42
|
+
if (options.stealthArgs !== false) {
|
|
43
|
+
args.push(...getDefaultStealthArgs());
|
|
44
|
+
}
|
|
45
|
+
if (options.args) {
|
|
46
|
+
args.push(...options.args);
|
|
47
|
+
}
|
|
48
|
+
return args;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=puppeteer.js.map
|
|
@@ -0,0 +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;AAE7C;;;;;;;;;;;;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;IAEhC,8DAA8D;IAC9D,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,kBAAkB,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/C,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,CAAC,qBAAqB,CAAC;QAC1C,GAAG,OAAO,CAAC,aAAa;KACzB,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,SAAS,SAAS,CAAC,OAAsB;IACvC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,GAAG,qBAAqB,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for cloakbrowser launch wrappers.
|
|
3
|
+
*/
|
|
4
|
+
export interface LaunchOptions {
|
|
5
|
+
/** Run in headless mode (default: true). */
|
|
6
|
+
headless?: boolean;
|
|
7
|
+
/** Proxy server URL, e.g. 'http://proxy:8080' or 'socks5://proxy:1080'. */
|
|
8
|
+
proxy?: string;
|
|
9
|
+
/** Additional Chromium CLI arguments. */
|
|
10
|
+
args?: string[];
|
|
11
|
+
/** Include default stealth fingerprint args (default: true). Set false to use custom --fingerprint flags. */
|
|
12
|
+
stealthArgs?: boolean;
|
|
13
|
+
/** Raw options passed directly to playwright/puppeteer launch(). */
|
|
14
|
+
launchOptions?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
export interface LaunchContextOptions extends LaunchOptions {
|
|
17
|
+
/** Custom user agent string. */
|
|
18
|
+
userAgent?: string;
|
|
19
|
+
/** Viewport size. */
|
|
20
|
+
viewport?: {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
};
|
|
24
|
+
/** Browser locale, e.g. "en-US". */
|
|
25
|
+
locale?: string;
|
|
26
|
+
/** Timezone, e.g. "America/New_York". */
|
|
27
|
+
timezoneId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface BinaryInfo {
|
|
30
|
+
version: string;
|
|
31
|
+
platform: string;
|
|
32
|
+
binaryPath: string;
|
|
33
|
+
installed: boolean;
|
|
34
|
+
cacheDir: string;
|
|
35
|
+
downloadUrl: string;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cloakbrowser",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Stealth Chromium that passes every bot detection test. Drop-in Playwright/Puppeteer replacement with source-level fingerprint patches.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./puppeteer": {
|
|
14
|
+
"types": "./dist/puppeteer.d.ts",
|
|
15
|
+
"import": "./dist/puppeteer.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"stealth",
|
|
23
|
+
"browser",
|
|
24
|
+
"chromium",
|
|
25
|
+
"playwright",
|
|
26
|
+
"puppeteer",
|
|
27
|
+
"scraping",
|
|
28
|
+
"anti-detect",
|
|
29
|
+
"bot-detection",
|
|
30
|
+
"fingerprint",
|
|
31
|
+
"recaptcha",
|
|
32
|
+
"cloudflare",
|
|
33
|
+
"datadome"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/CloakHQ/cloakbrowser",
|
|
39
|
+
"directory": "js"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/CloakHQ/cloakbrowser#javascript--nodejs",
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"playwright-core": ">=1.40.0",
|
|
47
|
+
"puppeteer-core": ">=21.0.0"
|
|
48
|
+
},
|
|
49
|
+
"peerDependenciesMeta": {
|
|
50
|
+
"playwright-core": {
|
|
51
|
+
"optional": true
|
|
52
|
+
},
|
|
53
|
+
"puppeteer-core": {
|
|
54
|
+
"optional": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"dependencies": {
|
|
58
|
+
"tar": "^7.0.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^20.10.0",
|
|
62
|
+
"playwright-core": "^1.40.0",
|
|
63
|
+
"puppeteer-core": "^21.0.0",
|
|
64
|
+
"typescript": "^5.3.0",
|
|
65
|
+
"vitest": "^1.0.0"
|
|
66
|
+
},
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "tsc",
|
|
69
|
+
"typecheck": "tsc --noEmit",
|
|
70
|
+
"test": "vitest run"
|
|
71
|
+
}
|
|
72
|
+
}
|