wreq-js 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/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 will-work-for-meal
4
+ Copyright (c) 2025 Oleksandr Herasymov
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # wreq-js
2
+
3
+ High-performance Node.js bindings for the Rust-based wreq HTTP client with native TLS and HTTP/2 browser impersonation.
4
+
5
+ Note: This is a personal fork of [will-work-for-meal/node-wreq](https://github.com/will-work-for-meal/node-wreq) (originally named node-wreq) with ongoing maintenance and faster dependency updates.
6
+
7
+ ## Features
8
+
9
+ - Native performance (no process spawning)
10
+ - TLS fingerprinting (JA3/JA4) aligned with real browsers
11
+ - HTTP/2 fingerprinting: SETTINGS, PRIORITY, and header ordering
12
+ - Multiple browser profiles (Chrome, Firefox, Safari, Edge, Opera, OkHttp)
13
+ - WebSocket support
14
+ - TypeScript definitions included
15
+
16
+ ## How It Works
17
+
18
+ The library provides Node.js bindings over [wreq](https://github.com/0x676e67/wreq), a Rust HTTP client that uses BoringSSL to replicate browser network behavior at the TLS and HTTP/2 layers.
19
+
20
+ ### Why It Works
21
+
22
+ Traditional HTTP clients (axios, fetch, curl) have differences in:
23
+ - **TLS handshake signatures** — Different cipher suites and extensions
24
+ - **HTTP/2 frame ordering** — Different SETTINGS and PRIORITY patterns
25
+ - **Header ordering** — Different sequence and values
26
+
27
+ This library reproduces browser network behavior with high fidelity.
28
+
29
+ ### Browser Profiles and wreq-util
30
+
31
+ - Browser profiles are generally tracked in the upstream `wreq-util` project; we depend on it for compatibility and support.
32
+ - Profiles in this package are available in `src/generated-types.ts` and are automatically generated from the `wreq-util` codebase to improve update speed and reduce maintenance overhead.
33
+ - Use `getProfiles()` to query the current set of supported profiles programmatically.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ # From GitHub (this fork)
39
+ # Latest master branch
40
+ npm install wreq-js
41
+ yarn add wreq-js
42
+ pnpm add wreq-js
43
+ bun add wreq-js
44
+
45
+ # From npm registry (original repo as node-wreq)
46
+ npm install node-wreq
47
+ yarn add node-wreq
48
+ pnpm add node-wreq
49
+ bun add node-wreq
50
+ ```
51
+
52
+ Pre-built native modules are included for major platforms:
53
+ - macOS (Intel and Apple Silicon)
54
+ - Linux (x64 and ARM64)
55
+ - Windows (x64)
56
+
57
+ Note on GitHub installs: if a matching prebuilt binary is not available for the referenced tag/commit, installation may build from source. Ensure a Rust toolchain and platform build prerequisites are installed.
58
+
59
+ ## Usage
60
+
61
+ ### Basic Request
62
+
63
+ ```typescript
64
+ import { request } from 'wreq-js';
65
+
66
+ const response = await request({
67
+ url: 'https://example.com/api',
68
+ browser: 'chrome_137',
69
+ });
70
+
71
+ console.log(response.status); // 200
72
+ console.log(response.body); // Response body
73
+ console.log(response.headers); // Response headers
74
+ console.log(response.cookies); // Cookies
75
+ ```
76
+
77
+ ### With Custom Headers
78
+
79
+ ```typescript
80
+ import { request } from 'wreq-js';
81
+
82
+ const response = await request({
83
+ url: 'https://api.example.com/data',
84
+ browser: 'firefox_139',
85
+ headers: {
86
+ 'Authorization': 'Bearer token123',
87
+ 'Custom-Header': 'value',
88
+ },
89
+ });
90
+ ```
91
+
92
+ ### POST Request
93
+
94
+ ```typescript
95
+ import { post } from 'wreq-js';
96
+
97
+ const response = await post(
98
+ 'https://api.example.com/submit',
99
+ JSON.stringify({ foo: 'bar' }),
100
+ {
101
+ browser: 'chrome_137',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ },
105
+ }
106
+ );
107
+ ```
108
+
109
+ ### Convenience Methods
110
+
111
+ ```typescript
112
+ import { get, post } from 'wreq-js';
113
+
114
+ // GET request
115
+ const data = await get('https://api.example.com/users');
116
+
117
+ // POST request
118
+ const result = await post(
119
+ 'https://api.example.com/users',
120
+ JSON.stringify({ name: 'John' })
121
+ );
122
+ ```
123
+
124
+ ### With Proxy
125
+
126
+ ```typescript
127
+ import { request } from 'wreq-js';
128
+
129
+ const response = await request({
130
+ url: 'https://example.com',
131
+ browser: 'chrome_137',
132
+ // proxy: 'http://proxy.example.com:8080',
133
+ // proxy: 'http://username:password@proxy.example.com:8080',
134
+ // proxy: 'socks5://proxy.example.com:1080',
135
+ });
136
+ ```
137
+
138
+ ### WebSocket Connection
139
+
140
+ ```typescript
141
+ import { websocket } from 'wreq-js';
142
+
143
+ const ws = await websocket({
144
+ url: 'wss://echo.websocket.org',
145
+ browser: 'chrome_137',
146
+ onMessage: (data) => {
147
+ console.log('Received:', data);
148
+ },
149
+ onClose: () => {
150
+ console.log('Connection closed');
151
+ },
152
+ onError: (error) => {
153
+ console.error('Error:', error);
154
+ },
155
+ });
156
+
157
+ // Send text message
158
+ await ws.send('Hello!');
159
+
160
+ // Send binary message
161
+ await ws.send(Buffer.from([1, 2, 3]));
162
+
163
+ // Close connection
164
+ await ws.close();
165
+ ```
166
+
167
+ ## API Reference
168
+
169
+ ### `request(options:` [`RequestOptions`](#requestoptions)`): Promise<`[`Response`](#response)`>`
170
+
171
+ Main function for making HTTP requests with browser impersonation.
172
+
173
+ **Options:**
174
+ <a name="requestoptions"></a>
175
+
176
+ ```typescript
177
+ interface RequestOptions {
178
+ url: string; // Required: URL to request
179
+ browser?: BrowserProfile; // Default: 'chrome_137'
180
+ method?: HttpMethod; // Default: 'GET'
181
+ headers?: Record<string, string>;
182
+ body?: string;
183
+ proxy?: string; // HTTP/HTTPS/SOCKS5 proxy URL
184
+ timeout?: number; // Default: 30000ms
185
+ }
186
+ ```
187
+
188
+ **Response:**
189
+ <a name="response"></a>
190
+
191
+ ```typescript
192
+ interface Response {
193
+ status: number;
194
+ headers: Record<string, string>;
195
+ body: string;
196
+ cookies: Record<string, string>;
197
+ url: string; // Final URL after redirects
198
+ }
199
+ ```
200
+
201
+ ### `get(url: string, options?): Promise<`[`Response`](#response)`>`
202
+
203
+ ### `post(url: string, body?: string, options?): Promise<`[`Response`](#response)`>`
204
+
205
+ ### `websocket(options:` [`WebSocketOptions`](#websocketoptions)`): Promise<WebSocket>`
206
+
207
+
208
+ **Options:**
209
+ <a name="websocketoptions"></a>
210
+
211
+ ```typescript
212
+ interface WebSocketOptions {
213
+ url: string; // Required: WebSocket URL (ws:// or wss://)
214
+ browser?: BrowserProfile; // Default: 'chrome_137'
215
+ headers?: Record<string, string>;
216
+ proxy?: string; // HTTP/HTTPS/SOCKS5 proxy URL
217
+ onMessage: (data: string | Buffer) => void; // Required: Message callback
218
+ onClose?: () => void; // Optional: Close callback
219
+ onError?: (error: string) => void; // Optional: Error callback
220
+ }
221
+ ```
222
+
223
+ **WebSocket Methods:**
224
+
225
+ ```typescript
226
+ class WebSocket {
227
+ send(data: string | Buffer): Promise<void>;
228
+ close(): Promise<void>;
229
+ }
230
+ ```
231
+
232
+ ### `getProfiles():` [`BrowserProfile[]`](#browser-profiles)
233
+
234
+ Get list of available browser profiles.
235
+
236
+ ```typescript
237
+ import { getProfiles } from 'wreq-js';
238
+
239
+ const profiles = getProfiles();
240
+
241
+ console.log(profiles);
242
+ // ['chrome_100', 'chrome_101', ..., 'chrome_137', 'edge_101', ..., 'safari_18', ...]
243
+ ```
244
+
245
+ ## Documentation
246
+
247
+ - **[Architecture Guide](docs/ARCHITECTURE.md)** — Technical details about TLS/HTTP2 fingerprinting, how browser impersonation works
248
+ - **[Build Instructions](docs/BUILD.md)** — Developer guide for building from source
249
+ - **[Publishing Guide](docs/PUBLISHING.md)** — How to publish the package
250
+
251
+ ## Contributing
252
+
253
+ Please read the [Contributing Guide](CONTRIBUTING.md).
254
+
255
+ ## Acknowledgments
256
+
257
+ - [wreq](https://github.com/0x676e67/wreq) — Rust HTTP client with browser impersonation
258
+ - [wreq-util](https://github.com/0x676e67/wreq-util) — Upstream utility project that tracks and ships browser fingerprint updates rapidly
259
+ - [Neon](https://neon-bindings.com/) — Rust ↔ Node.js bindings
260
+ - Original Node.js wrapper: [will-work-for-meal/node-wreq](https://github.com/will-work-for-meal/node-wreq) (named node-wreq) — clean, well-written baseline this fork builds on
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Auto-generated from Rust build script
3
+ * DO NOT EDIT MANUALLY
4
+ */
5
+ /**
6
+ * Browser profile names supported
7
+ */
8
+ export type BrowserProfile = 'chrome_100' | 'chrome_101' | 'chrome_104' | 'chrome_105' | 'chrome_106' | 'chrome_107' | 'chrome_108' | 'chrome_109' | 'chrome_110' | 'chrome_114' | 'chrome_116' | 'chrome_117' | 'chrome_118' | 'chrome_119' | 'chrome_120' | 'chrome_123' | 'chrome_124' | 'chrome_126' | 'chrome_127' | 'chrome_128' | 'chrome_129' | 'chrome_130' | 'chrome_131' | 'chrome_132' | 'chrome_133' | 'chrome_134' | 'chrome_135' | 'chrome_136' | 'chrome_137' | 'chrome_138' | 'chrome_139' | 'chrome_140' | 'chrome_141' | 'chrome_142' | 'edge_101' | 'edge_122' | 'edge_127' | 'edge_131' | 'edge_134' | 'opera_116' | 'opera_117' | 'opera_118' | 'opera_119' | 'safari_ios_17.2' | 'safari_ios_17.4.1' | 'safari_ios_16.5' | 'safari_15.3' | 'safari_15.5' | 'safari_15.6.1' | 'safari_16' | 'safari_16.5' | 'safari_17.0' | 'safari_17.2.1' | 'safari_17.4.1' | 'safari_17.5' | 'safari_18' | 'safari_ipad_18' | 'safari_18.2' | 'safari_ios_18.1.1' | 'safari_18.3' | 'safari_18.3.1' | 'safari_18.5' | 'safari_26' | 'safari_ipad_26' | 'safari_ios_26' | 'firefox_109' | 'firefox_117' | 'firefox_128' | 'firefox_133' | 'firefox_135' | 'firefox_private_135' | 'firefox_android_135' | 'firefox_136' | 'firefox_private_136' | 'firefox_139' | 'firefox_142' | 'firefox_143' | 'okhttp_3.9' | 'okhttp_3.11' | 'okhttp_3.13' | 'okhttp_3.14' | 'okhttp_4.9' | 'okhttp_4.10' | 'okhttp_4.12' | 'okhttp_5';
9
+ //# sourceMappingURL=generated-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generated-types.d.ts","sourceRoot":"","sources":["../src/generated-types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,UAAU,GACV,UAAU,GACV,UAAU,GACV,UAAU,GACV,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,iBAAiB,GACjB,mBAAmB,GACnB,iBAAiB,GACjB,aAAa,GACb,aAAa,GACb,eAAe,GACf,WAAW,GACX,aAAa,GACb,aAAa,GACb,eAAe,GACf,eAAe,GACf,aAAa,GACb,WAAW,GACX,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,aAAa,GACb,eAAe,GACf,aAAa,GACb,WAAW,GACX,gBAAgB,GAChB,eAAe,GACf,aAAa,GACb,aAAa,GACb,aAAa,GACb,aAAa,GACb,aAAa,GACb,qBAAqB,GACrB,qBAAqB,GACrB,aAAa,GACb,qBAAqB,GACrB,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,aAAa,GACb,aAAa,GACb,aAAa,GACb,YAAY,GACZ,aAAa,GACb,aAAa,GACb,UAAU,CAAC"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ /**
3
+ * Auto-generated from Rust build script
4
+ * DO NOT EDIT MANUALLY
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ //# sourceMappingURL=generated-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generated-types.js","sourceRoot":"","sources":["../src/generated-types.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.spec.d.ts","sourceRoot":"","sources":["../../src/test/http.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const node_assert_1 = __importDefault(require("node:assert"));
8
+ const wreq_js_1 = require("../wreq-js");
9
+ (0, node_test_1.describe)('HTTP', () => {
10
+ (0, node_test_1.before)(() => {
11
+ console.log('🔌 HTTP Test Suite\n');
12
+ });
13
+ (0, node_test_1.test)('should return available browser profiles', () => {
14
+ const profiles = (0, wreq_js_1.getProfiles)();
15
+ node_assert_1.default.ok(Array.isArray(profiles), 'Profiles should be an array');
16
+ node_assert_1.default.ok(profiles.length > 0, 'Should have at least one profile');
17
+ node_assert_1.default.ok(profiles.some((p) => p.includes('chrome')) ||
18
+ profiles.some((p) => p.includes('firefox')) ||
19
+ profiles.some((p) => p.includes('safari')), 'Should include standard browser profiles');
20
+ console.log('Available profiles:', profiles.join(', '));
21
+ });
22
+ (0, node_test_1.test)('should make a simple GET request', async () => {
23
+ const response = await (0, wreq_js_1.request)({
24
+ url: 'https://httpbingo.org/get',
25
+ browser: 'chrome_131',
26
+ timeout: 10000,
27
+ });
28
+ node_assert_1.default.ok(response.status >= 200 && response.status < 300, 'Should return successful status');
29
+ node_assert_1.default.ok(Object.keys(response.headers).length > 0, 'Should have response headers');
30
+ node_assert_1.default.ok(response.body.length > 0, 'Should have response body');
31
+ const body = JSON.parse(response.body);
32
+ node_assert_1.default.ok(body.headers['User-Agent'], 'Should have User-Agent header');
33
+ console.log('Status:', response.status);
34
+ console.log('User-Agent:', body.headers['User-Agent']);
35
+ });
36
+ (0, node_test_1.test)('should work with different browser profiles', async () => {
37
+ const testUrl = 'https://httpbingo.org/user-agent';
38
+ const browsers = ['chrome_137', 'firefox_139', 'safari_18'];
39
+ for (const browser of browsers) {
40
+ const response = await (0, wreq_js_1.request)({
41
+ url: testUrl,
42
+ browser: browser,
43
+ timeout: 10000,
44
+ });
45
+ node_assert_1.default.ok(response.status === 200, `${browser} should return status 200`);
46
+ const data = JSON.parse(response.body);
47
+ node_assert_1.default.ok(data['user-agent'], `${browser} should have user-agent`);
48
+ console.log(`${browser}:`, data['user-agent'].substring(0, 70) + '...');
49
+ }
50
+ });
51
+ (0, node_test_1.test)('should handle timeout errors', async () => {
52
+ await node_assert_1.default.rejects(async () => {
53
+ await (0, wreq_js_1.request)({
54
+ url: 'https://httpbingo.org/delay/10',
55
+ browser: 'chrome_137',
56
+ timeout: 1000, // 1 second timeout for 10 second delay
57
+ });
58
+ }, {
59
+ name: 'RequestError',
60
+ }, 'Should throw an error on timeout');
61
+ });
62
+ });
63
+ //# sourceMappingURL=http.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.spec.js","sourceRoot":"","sources":["../../src/test/http.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=websocket.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.spec.d.ts","sourceRoot":"","sources":["../../src/test/websocket.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const node_assert_1 = __importDefault(require("node:assert"));
8
+ const promises_1 = require("node:timers/promises");
9
+ const wreq_js_1 = require("../wreq-js");
10
+ (0, node_test_1.describe)('WebSocket', () => {
11
+ (0, node_test_1.before)(() => {
12
+ console.log('🔌 WebSocket Test Suite\n');
13
+ });
14
+ (0, node_test_1.test)('should connect to WebSocket and send/receive messages', async () => {
15
+ const messages = [];
16
+ let isClosed = false;
17
+ const ws = await (0, wreq_js_1.websocket)({
18
+ url: 'wss://echo.websocket.org',
19
+ browser: 'chrome_137',
20
+ onMessage: (data) => {
21
+ messages.push(data);
22
+ },
23
+ onClose: () => {
24
+ isClosed = true;
25
+ },
26
+ onError: (error) => {
27
+ console.error('WebSocket error:', error);
28
+ },
29
+ });
30
+ console.log('WebSocket connected');
31
+ await ws.send('Hello!');
32
+ // Wait for echo response
33
+ await (0, promises_1.setTimeout)(1000);
34
+ node_assert_1.default.ok(messages.length > 0, 'Should receive at least one message');
35
+ // Wait a bit for close callback
36
+ await ws.close();
37
+ await (0, promises_1.setTimeout)(5000);
38
+ node_assert_1.default.ok(isClosed, 'Should receive close event');
39
+ // Rate limit protection: wait before next test
40
+ await (0, promises_1.setTimeout)(2000);
41
+ });
42
+ (0, node_test_1.test)('should handle parallel sends on same WebSocket', async () => {
43
+ const messages = [];
44
+ const expectedMessages = ['Message 1', 'Message 2', 'Message 3', 'Message 4', 'Message 5'];
45
+ const ws = await (0, wreq_js_1.websocket)({
46
+ url: 'wss://echo.websocket.org',
47
+ browser: 'chrome_137',
48
+ onMessage: (data) => {
49
+ messages.push(data);
50
+ },
51
+ onClose: () => { },
52
+ onError: (error) => {
53
+ console.error('WebSocket error:', error);
54
+ },
55
+ });
56
+ console.log('Testing parallel sends...');
57
+ // Send multiple messages in parallel
58
+ await Promise.all([
59
+ ws.send('Message 1'),
60
+ ws.send('Message 2'),
61
+ ws.send('Message 3'),
62
+ ws.send('Message 4'),
63
+ ws.send('Message 5'),
64
+ ]);
65
+ console.log('All messages sent in parallel');
66
+ // Wait for echo responses
67
+ await (0, promises_1.setTimeout)(2000);
68
+ node_assert_1.default.ok(messages.length >= 5, 'Should receive at least 5 messages');
69
+ // Verify that all expected messages were received (order may vary)
70
+ const receivedStrings = messages.map((m) => (Buffer.isBuffer(m) ? m.toString() : m));
71
+ for (const expected of expectedMessages) {
72
+ node_assert_1.default.ok(receivedStrings.includes(expected), `Should receive message: "${expected}". Got: ${receivedStrings.join(', ')}`);
73
+ }
74
+ console.log('All messages received correctly:', receivedStrings.join(', '));
75
+ await ws.close();
76
+ // Rate limit protection: wait before next test
77
+ await (0, promises_1.setTimeout)(2000);
78
+ });
79
+ (0, node_test_1.test)('should handle multiple WebSocket connections simultaneously', async () => {
80
+ const ws1Messages = [];
81
+ const ws2Messages = [];
82
+ // Create two WebSocket connections in parallel
83
+ const [ws1, ws2] = await Promise.all([
84
+ (0, wreq_js_1.websocket)({
85
+ url: 'wss://echo.websocket.org',
86
+ browser: 'chrome_137',
87
+ onMessage: (data) => ws1Messages.push(data),
88
+ onClose: () => { },
89
+ onError: () => { },
90
+ }),
91
+ (0, wreq_js_1.websocket)({
92
+ url: 'wss://echo.websocket.org',
93
+ browser: 'firefox_139',
94
+ onMessage: (data) => ws2Messages.push(data),
95
+ onClose: () => { },
96
+ onError: () => { },
97
+ }),
98
+ ]);
99
+ console.log('WebSocket connections created');
100
+ // Send unique messages on both connections in parallel
101
+ await Promise.all([ws1.send('From WS1'), ws2.send('From WS2')]);
102
+ // Wait for responses
103
+ await (0, promises_1.setTimeout)(1500);
104
+ node_assert_1.default.ok(ws1Messages.length > 0, 'WS1 should receive messages');
105
+ node_assert_1.default.ok(ws2Messages.length > 0, 'WS2 should receive messages');
106
+ // Verify that each connection received the correct message (not mixed up)
107
+ // Note: echo.websocket.org sends a "Request served by..." message first, then echoes
108
+ const ws1Strings = ws1Messages.map((m) => (Buffer.isBuffer(m) ? m.toString() : m));
109
+ const ws2Strings = ws2Messages.map((m) => (Buffer.isBuffer(m) ? m.toString() : m));
110
+ node_assert_1.default.ok(ws1Strings.includes('From WS1'), 'WS1 should receive its own message');
111
+ node_assert_1.default.ok(ws2Strings.includes('From WS2'), 'WS2 should receive its own message');
112
+ // Verify messages are not mixed up between connections
113
+ node_assert_1.default.ok(!ws1Strings.includes('From WS2'), 'WS1 should NOT receive WS2 message');
114
+ node_assert_1.default.ok(!ws2Strings.includes('From WS1'), 'WS2 should NOT receive WS1 message');
115
+ console.log('Messages correctly isolated between connections:');
116
+ console.log(' WS1:', ws1Strings);
117
+ console.log(' WS2:', ws2Strings);
118
+ // Close both connections
119
+ await Promise.all([ws1.close(), ws2.close()]);
120
+ });
121
+ });
122
+ //# sourceMappingURL=websocket.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.spec.js","sourceRoot":"","sources":["../../src/test/websocket.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import type { BrowserProfile } from './generated-types';
2
+ export type { BrowserProfile };
3
+ /**
4
+ * HTTP method types
5
+ */
6
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD';
7
+ /**
8
+ * Request options for making HTTP requests with browser impersonation
9
+ */
10
+ export interface RequestOptions {
11
+ /**
12
+ * The URL to request
13
+ */
14
+ url: string;
15
+ /**
16
+ * Browser profile to impersonate
17
+ * @default 'chrome_137'
18
+ */
19
+ browser?: BrowserProfile;
20
+ /**
21
+ * HTTP method
22
+ * @default 'GET'
23
+ */
24
+ method?: HttpMethod;
25
+ /**
26
+ * Additional headers to send with the request
27
+ * Browser-specific headers will be automatically added
28
+ */
29
+ headers?: Record<string, string>;
30
+ /**
31
+ * Request body (for POST, PUT, PATCH requests)
32
+ */
33
+ body?: string;
34
+ /**
35
+ * Proxy URL (e.g., 'http://proxy.example.com:8080')
36
+ */
37
+ proxy?: string;
38
+ /**
39
+ * Request timeout in milliseconds
40
+ * @default 30000
41
+ */
42
+ timeout?: number;
43
+ }
44
+ /**
45
+ * Response object returned from HTTP requests
46
+ */
47
+ export interface Response {
48
+ /**
49
+ * HTTP status code
50
+ */
51
+ status: number;
52
+ /**
53
+ * Response headers
54
+ */
55
+ headers: Record<string, string>;
56
+ /**
57
+ * Response body as string
58
+ */
59
+ body: string;
60
+ /**
61
+ * Cookies set by the server
62
+ */
63
+ cookies: Record<string, string>;
64
+ /**
65
+ * Final URL after redirects
66
+ */
67
+ url: string;
68
+ }
69
+ /**
70
+ * WebSocket options for creating a connection
71
+ */
72
+ export interface WebSocketOptions {
73
+ /**
74
+ * The WebSocket URL to connect to (wss:// or ws://)
75
+ */
76
+ url: string;
77
+ /**
78
+ * Browser profile to impersonate
79
+ * @default 'chrome_137'
80
+ */
81
+ browser?: BrowserProfile;
82
+ /**
83
+ * Additional headers to send with the WebSocket upgrade request
84
+ */
85
+ headers?: Record<string, string>;
86
+ /**
87
+ * Proxy URL (e.g., 'http://proxy.example.com:8080')
88
+ */
89
+ proxy?: string;
90
+ /**
91
+ * Callback for incoming messages (required)
92
+ */
93
+ onMessage: (data: string | Buffer) => void;
94
+ /**
95
+ * Callback for connection close event
96
+ */
97
+ onClose?: () => void;
98
+ /**
99
+ * Callback for error events
100
+ */
101
+ onError?: (error: string) => void;
102
+ }
103
+ /**
104
+ * Internal WebSocket connection object returned from native binding
105
+ */
106
+ export interface NativeWebSocketConnection {
107
+ _id: number;
108
+ }
109
+ export declare class RequestError extends Error {
110
+ constructor(message: string);
111
+ }
112
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM;CAI5B"}
package/dist/types.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RequestError = void 0;
4
+ class RequestError extends Error {
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = 'RequestError';
8
+ }
9
+ }
10
+ exports.RequestError = RequestError;
11
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAmIA,MAAa,YAAa,SAAQ,KAAK;IACrC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AALD,oCAKC"}
@@ -0,0 +1,136 @@
1
+ import type { RequestOptions, Response, BrowserProfile, WebSocketOptions, NativeWebSocketConnection } from './types';
2
+ import { RequestError } from './types';
3
+ /**
4
+ * Make an HTTP request with browser impersonation
5
+ *
6
+ * @param options - Request options
7
+ * @returns Promise that resolves to the response
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { request } from 'wreq-js';
12
+ *
13
+ * const response = await request({
14
+ * url: 'https://example.com/api',
15
+ * browser: 'chrome_137',
16
+ * headers: {
17
+ * 'Custom-Header': 'value'
18
+ * }
19
+ * });
20
+ *
21
+ * console.log(response.status); // 200
22
+ * console.log(response.body); // Response body
23
+ * ```
24
+ */
25
+ export declare function request(options: RequestOptions): Promise<Response>;
26
+ /**
27
+ * Get list of available browser profiles
28
+ *
29
+ * @returns Array of browser profile names
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { getProfiles } from 'wreq-js';
34
+ *
35
+ * const profiles = getProfiles();
36
+ * console.log(profiles); // ['chrome_120', 'chrome_131', 'firefox', ...]
37
+ * ```
38
+ */
39
+ export declare function getProfiles(): BrowserProfile[];
40
+ /**
41
+ * Convenience function for GET requests
42
+ *
43
+ * @param url - URL to request
44
+ * @param options - Additional request options
45
+ * @returns Promise that resolves to the response
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * import { get } from 'wreq-js';
50
+ *
51
+ * const response = await get('https://example.com/api');
52
+ * ```
53
+ */
54
+ export declare function get(url: string, options?: Omit<RequestOptions, 'url' | 'method'>): Promise<Response>;
55
+ /**
56
+ * Convenience function for POST requests
57
+ *
58
+ * @param url - URL to request
59
+ * @param body - Request body
60
+ * @param options - Additional request options
61
+ * @returns Promise that resolves to the response
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * import { post } from 'wreq-js';
66
+ *
67
+ * const response = await post(
68
+ * 'https://example.com/api',
69
+ * JSON.stringify({ foo: 'bar' }),
70
+ * { headers: { 'Content-Type': 'application/json' } }
71
+ * );
72
+ * ```
73
+ */
74
+ export declare function post(url: string, body?: string, options?: Omit<RequestOptions, 'url' | 'method' | 'body'>): Promise<Response>;
75
+ /**
76
+ * WebSocket connection class
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * import { websocket } from 'wreq-js';
81
+ *
82
+ * const ws = await websocket({
83
+ * url: 'wss://echo.websocket.org',
84
+ * browser: 'chrome_137',
85
+ * onMessage: (data) => {
86
+ * console.log('Received:', data);
87
+ * },
88
+ * onClose: () => {
89
+ * console.log('Connection closed');
90
+ * },
91
+ * onError: (error) => {
92
+ * console.error('Error:', error);
93
+ * }
94
+ * });
95
+ *
96
+ * // Send text message
97
+ * await ws.send('Hello World');
98
+ *
99
+ * // Send binary message
100
+ * await ws.send(Buffer.from([1, 2, 3]));
101
+ *
102
+ * // Close connection
103
+ * await ws.close();
104
+ * ```
105
+ */
106
+ export declare class WebSocket {
107
+ private _connection;
108
+ constructor(connection: NativeWebSocketConnection);
109
+ /**
110
+ * Send a message (text or binary)
111
+ */
112
+ send(data: string | Buffer): Promise<void>;
113
+ /**
114
+ * Close the WebSocket connection
115
+ */
116
+ close(): Promise<void>;
117
+ }
118
+ /**
119
+ * Create a WebSocket connection with browser impersonation
120
+ *
121
+ * @param options - WebSocket options
122
+ * @returns Promise that resolves to the WebSocket instance
123
+ */
124
+ export declare function websocket(options: WebSocketOptions): Promise<WebSocket>;
125
+ export type { RequestOptions, Response, BrowserProfile, HttpMethod, WebSocketOptions, } from './types';
126
+ export type { RequestError };
127
+ declare const _default: {
128
+ request: typeof request;
129
+ get: typeof get;
130
+ post: typeof post;
131
+ getProfiles: typeof getProfiles;
132
+ websocket: typeof websocket;
133
+ WebSocket: typeof WebSocket;
134
+ };
135
+ export default _default;
136
+ //# sourceMappingURL=wreq-js.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wreq-js.d.ts","sourceRoot":"","sources":["../src/wreq-js.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA0EvC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC,CAoBxE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAE9C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,GAAG,CACvB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,QAAQ,CAAC,GAC/C,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,IAAI,CACxB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC,GACxD,OAAO,CAAC,QAAQ,CAAC,CAEnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,WAAW,CAA4B;gBAEnC,UAAU,EAAE,yBAAyB;IAIjD;;OAEG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQhD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAO7B;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAkC7E;AAED,YAAY,EACV,cAAc,EACd,QAAQ,EACR,cAAc,EACd,UAAU,EACV,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,YAAY,EAAE,CAAC;;;;;;;;;AAE7B,wBAOE"}
@@ -0,0 +1,253 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocket = void 0;
4
+ exports.request = request;
5
+ exports.getProfiles = getProfiles;
6
+ exports.get = get;
7
+ exports.post = post;
8
+ exports.websocket = websocket;
9
+ const types_1 = require("./types");
10
+ let nativeBinding;
11
+ function loadNativeBinding() {
12
+ const platform = process.platform;
13
+ const arch = process.arch;
14
+ // Map Node.js platform/arch to Rust target triple suffixes
15
+ // napi-rs creates files like: wreq-js.linux-x64-gnu.node
16
+ const platformArchMap = {
17
+ darwin: {
18
+ x64: 'darwin-x64',
19
+ arm64: 'darwin-arm64',
20
+ },
21
+ linux: {
22
+ x64: 'linux-x64-gnu',
23
+ arm64: 'linux-arm64-gnu',
24
+ },
25
+ win32: {
26
+ x64: 'win32-x64-msvc',
27
+ },
28
+ };
29
+ const platformArch = platformArchMap[platform]?.[arch];
30
+ if (!platformArch) {
31
+ throw new Error(`Unsupported platform: ${platform}-${arch}. ` +
32
+ `Supported platforms: darwin-x64, darwin-arm64, linux-x64, linux-arm64, win32-x64`);
33
+ }
34
+ // Try to load platform-specific binary
35
+ const binaryName = `wreq-js.${platformArch}.node`;
36
+ try {
37
+ return require(`../rust/${binaryName}`);
38
+ }
39
+ catch (e1) {
40
+ // Fallback to wreq-js.node (for local development)
41
+ try {
42
+ return require('../rust/wreq-js.node');
43
+ }
44
+ catch (e2) {
45
+ throw new Error(`Failed to load native module for ${platform}-${arch}. ` +
46
+ `Tried: ../rust/${binaryName} and ../rust/wreq-js.node. ` +
47
+ `Make sure the package is installed correctly and the native module is built for your platform.`);
48
+ }
49
+ }
50
+ }
51
+ try {
52
+ nativeBinding = loadNativeBinding();
53
+ }
54
+ catch (error) {
55
+ throw error;
56
+ }
57
+ /**
58
+ * Make an HTTP request with browser impersonation
59
+ *
60
+ * @param options - Request options
61
+ * @returns Promise that resolves to the response
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * import { request } from 'wreq-js';
66
+ *
67
+ * const response = await request({
68
+ * url: 'https://example.com/api',
69
+ * browser: 'chrome_137',
70
+ * headers: {
71
+ * 'Custom-Header': 'value'
72
+ * }
73
+ * });
74
+ *
75
+ * console.log(response.status); // 200
76
+ * console.log(response.body); // Response body
77
+ * ```
78
+ */
79
+ async function request(options) {
80
+ if (!options.url) {
81
+ throw new types_1.RequestError('URL is required');
82
+ }
83
+ if (options.browser) {
84
+ const profiles = getProfiles();
85
+ if (!profiles.includes(options.browser)) {
86
+ throw new types_1.RequestError(`Invalid browser profile: ${options.browser}. Available profiles: ${profiles.join(', ')}`);
87
+ }
88
+ }
89
+ try {
90
+ return await nativeBinding.request(options);
91
+ }
92
+ catch (error) {
93
+ throw new types_1.RequestError(String(error));
94
+ }
95
+ }
96
+ /**
97
+ * Get list of available browser profiles
98
+ *
99
+ * @returns Array of browser profile names
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * import { getProfiles } from 'wreq-js';
104
+ *
105
+ * const profiles = getProfiles();
106
+ * console.log(profiles); // ['chrome_120', 'chrome_131', 'firefox', ...]
107
+ * ```
108
+ */
109
+ function getProfiles() {
110
+ return nativeBinding.getProfiles();
111
+ }
112
+ /**
113
+ * Convenience function for GET requests
114
+ *
115
+ * @param url - URL to request
116
+ * @param options - Additional request options
117
+ * @returns Promise that resolves to the response
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * import { get } from 'wreq-js';
122
+ *
123
+ * const response = await get('https://example.com/api');
124
+ * ```
125
+ */
126
+ async function get(url, options) {
127
+ return request({ ...options, url, method: 'GET' });
128
+ }
129
+ /**
130
+ * Convenience function for POST requests
131
+ *
132
+ * @param url - URL to request
133
+ * @param body - Request body
134
+ * @param options - Additional request options
135
+ * @returns Promise that resolves to the response
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * import { post } from 'wreq-js';
140
+ *
141
+ * const response = await post(
142
+ * 'https://example.com/api',
143
+ * JSON.stringify({ foo: 'bar' }),
144
+ * { headers: { 'Content-Type': 'application/json' } }
145
+ * );
146
+ * ```
147
+ */
148
+ async function post(url, body, options) {
149
+ return request({ ...options, url, method: 'POST', body });
150
+ }
151
+ /**
152
+ * WebSocket connection class
153
+ *
154
+ * @example
155
+ * ```typescript
156
+ * import { websocket } from 'wreq-js';
157
+ *
158
+ * const ws = await websocket({
159
+ * url: 'wss://echo.websocket.org',
160
+ * browser: 'chrome_137',
161
+ * onMessage: (data) => {
162
+ * console.log('Received:', data);
163
+ * },
164
+ * onClose: () => {
165
+ * console.log('Connection closed');
166
+ * },
167
+ * onError: (error) => {
168
+ * console.error('Error:', error);
169
+ * }
170
+ * });
171
+ *
172
+ * // Send text message
173
+ * await ws.send('Hello World');
174
+ *
175
+ * // Send binary message
176
+ * await ws.send(Buffer.from([1, 2, 3]));
177
+ *
178
+ * // Close connection
179
+ * await ws.close();
180
+ * ```
181
+ */
182
+ class WebSocket {
183
+ constructor(connection) {
184
+ this._connection = connection;
185
+ }
186
+ /**
187
+ * Send a message (text or binary)
188
+ */
189
+ async send(data) {
190
+ try {
191
+ await nativeBinding.websocketSend(this._connection, data);
192
+ }
193
+ catch (error) {
194
+ throw new types_1.RequestError(String(error));
195
+ }
196
+ }
197
+ /**
198
+ * Close the WebSocket connection
199
+ */
200
+ async close() {
201
+ try {
202
+ await nativeBinding.websocketClose(this._connection);
203
+ }
204
+ catch (error) {
205
+ throw new types_1.RequestError(String(error));
206
+ }
207
+ }
208
+ }
209
+ exports.WebSocket = WebSocket;
210
+ /**
211
+ * Create a WebSocket connection with browser impersonation
212
+ *
213
+ * @param options - WebSocket options
214
+ * @returns Promise that resolves to the WebSocket instance
215
+ */
216
+ async function websocket(options) {
217
+ if (!options.url) {
218
+ throw new types_1.RequestError('URL is required');
219
+ }
220
+ if (!options.onMessage) {
221
+ throw new types_1.RequestError('onMessage callback is required');
222
+ }
223
+ if (options.browser) {
224
+ const profiles = getProfiles();
225
+ if (!profiles.includes(options.browser)) {
226
+ throw new types_1.RequestError(`Invalid browser profile: ${options.browser}. Available profiles: ${profiles.join(', ')}`);
227
+ }
228
+ }
229
+ try {
230
+ const connection = await nativeBinding.websocketConnect({
231
+ url: options.url,
232
+ browser: options.browser || 'chrome_137',
233
+ headers: options.headers || {},
234
+ proxy: options.proxy,
235
+ onMessage: options.onMessage,
236
+ onClose: options.onClose,
237
+ onError: options.onError,
238
+ });
239
+ return new WebSocket(connection);
240
+ }
241
+ catch (error) {
242
+ throw new types_1.RequestError(String(error));
243
+ }
244
+ }
245
+ exports.default = {
246
+ request,
247
+ get,
248
+ post,
249
+ getProfiles,
250
+ websocket,
251
+ WebSocket,
252
+ };
253
+ //# sourceMappingURL=wreq-js.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wreq-js.js","sourceRoot":"","sources":["../src/wreq-js.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "wreq-js",
3
+ "version": "0.1.0",
4
+ "description": "Browser fingerprint bypass library using Rust for TLS/HTTP2 impersonation",
5
+ "main": "dist/wreq-js.js",
6
+ "types": "dist/wreq-js.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/wreq-js.d.ts",
10
+ "require": "./dist/wreq-js.js",
11
+ "import": "./dist/wreq-js.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "npm run build:rust && npm run build:ts",
16
+ "build:rust": "napi build --platform --release --cargo-cwd rust rust",
17
+ "build:ts": "npm run clean:dist && tsc",
18
+ "clean:dist": "rimraf dist",
19
+ "artifacts": "napi artifacts",
20
+ "clean": "rimraf dist rust/target rust/*.node",
21
+ "test": "npm run build && node --test dist/test/http.spec.js dist/test/websocket.spec.js",
22
+ "format": "prettier --write \"src/**/*.{ts,js,json,md}\"",
23
+ "format:check": "prettier --check \"src/**/*.{ts,js,json,md}\""
24
+ },
25
+ "keywords": [
26
+ "browser",
27
+ "fingerprint",
28
+ "bypass",
29
+ "anti-bot",
30
+ "tls",
31
+ "http2",
32
+ "impersonation",
33
+ "web-scraping",
34
+ "crawler",
35
+ "web-scraper",
36
+ "wreq",
37
+ "ja3",
38
+ "tls-fingerprint",
39
+ "ja4",
40
+ "browser-fingerprint-bypass"
41
+ ],
42
+ "author": "Oleksandr Herasymov <herasymov7@icloud.com>",
43
+ "contributors": [
44
+ "will-work-for-meal"
45
+ ],
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/sqdshguy/wreq-js.git"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/sqdshguy/wreq-js/issues"
53
+ },
54
+ "homepage": "https://github.com/sqdshguy/wreq-js#readme",
55
+ "devDependencies": {
56
+ "@napi-rs/cli": "^2.18.0",
57
+ "@types/node": "^20.0.0",
58
+ "prettier": "^3.2.5",
59
+ "rimraf": "^6.0.1",
60
+ "typescript": "^5.0.0"
61
+ },
62
+ "engines": {
63
+ "node": ">=20.0.0"
64
+ },
65
+ "os": [
66
+ "darwin",
67
+ "linux",
68
+ "win32"
69
+ ],
70
+ "cpu": [
71
+ "x64",
72
+ "arm64"
73
+ ],
74
+ "files": [
75
+ "dist",
76
+ "rust/*.node"
77
+ ],
78
+ "napi": {
79
+ "name": "wreq-js",
80
+ "triples": {
81
+ "defaults": true,
82
+ "additional": [
83
+ "x86_64-apple-darwin",
84
+ "aarch64-apple-darwin",
85
+ "x86_64-unknown-linux-gnu",
86
+ "aarch64-unknown-linux-gnu",
87
+ "x86_64-pc-windows-msvc"
88
+ ]
89
+ }
90
+ }
91
+ }
Binary file
Binary file
Binary file
Binary file