httpcloak 1.6.1-beta.2 → 1.6.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 CHANGED
@@ -16,7 +16,7 @@ npm install httpcloak
16
16
  const { Session } = require("httpcloak");
17
17
 
18
18
  async function main() {
19
- const session = new Session({ preset: "chrome-145" });
19
+ const session = new Session({ preset: "chrome-latest" });
20
20
 
21
21
  try {
22
22
  // GET request
@@ -53,7 +53,7 @@ main();
53
53
  ```javascript
54
54
  import { Session } from "httpcloak";
55
55
 
56
- const session = new Session({ preset: "chrome-145" });
56
+ const session = new Session({ preset: "chrome-latest" });
57
57
 
58
58
  const response = await session.get("https://example.com");
59
59
  console.log(response.text);
@@ -66,7 +66,7 @@ session.close();
66
66
  ```javascript
67
67
  const { Session } = require("httpcloak");
68
68
 
69
- const session = new Session({ preset: "chrome-145" });
69
+ const session = new Session({ preset: "chrome-latest" });
70
70
 
71
71
  // Sync GET
72
72
  const response = session.getSync("https://example.com");
@@ -86,7 +86,7 @@ session.close();
86
86
  ```javascript
87
87
  const { Session } = require("httpcloak");
88
88
 
89
- const session = new Session({ preset: "chrome-145" });
89
+ const session = new Session({ preset: "chrome-latest" });
90
90
 
91
91
  // GET with callback
92
92
  session.getCb("https://example.com", (err, response) => {
@@ -121,7 +121,7 @@ const { Session } = require("httpcloak");
121
121
  const fs = require("fs");
122
122
 
123
123
  async function downloadFile() {
124
- const session = new Session({ preset: "chrome-145" });
124
+ const session = new Session({ preset: "chrome-latest" });
125
125
 
126
126
  try {
127
127
  // Start streaming request
@@ -158,7 +158,7 @@ downloadFile();
158
158
  ```javascript
159
159
  const { Session } = require("httpcloak");
160
160
 
161
- const session = new Session({ preset: "chrome-145" });
161
+ const session = new Session({ preset: "chrome-latest" });
162
162
 
163
163
  // Stream GET
164
164
  const getStream = session.getStream("https://example.com/data");
@@ -195,19 +195,19 @@ const { Session } = require("httpcloak");
195
195
 
196
196
  // Basic HTTP proxy
197
197
  const session = new Session({
198
- preset: "chrome-145",
198
+ preset: "chrome-latest",
199
199
  proxy: "http://host:port",
200
200
  });
201
201
 
202
202
  // With authentication
203
203
  const sessionAuth = new Session({
204
- preset: "chrome-145",
204
+ preset: "chrome-latest",
205
205
  proxy: "http://user:pass@host:port",
206
206
  });
207
207
 
208
208
  // HTTPS proxy
209
209
  const sessionHttps = new Session({
210
- preset: "chrome-145",
210
+ preset: "chrome-latest",
211
211
  proxy: "https://user:pass@host:port",
212
212
  });
213
213
  ```
@@ -219,13 +219,13 @@ const { Session } = require("httpcloak");
219
219
 
220
220
  // SOCKS5 proxy (with DNS resolution on proxy)
221
221
  const session = new Session({
222
- preset: "chrome-145",
222
+ preset: "chrome-latest",
223
223
  proxy: "socks5h://host:port",
224
224
  });
225
225
 
226
226
  // With authentication
227
227
  const sessionAuth = new Session({
228
- preset: "chrome-145",
228
+ preset: "chrome-latest",
229
229
  proxy: "socks5h://user:pass@host:port",
230
230
  });
231
231
 
@@ -242,7 +242,7 @@ const { Session } = require("httpcloak");
242
242
 
243
243
  // MASQUE proxy (auto-detected for known providers like Bright Data)
244
244
  const session = new Session({
245
- preset: "chrome-145",
245
+ preset: "chrome-latest",
246
246
  proxy: "https://user:pass@brd.superproxy.io:10001",
247
247
  });
248
248
 
@@ -258,7 +258,7 @@ Use different proxies for TCP (HTTP/1.1, HTTP/2) and UDP (HTTP/3) traffic:
258
258
  const { Session } = require("httpcloak");
259
259
 
260
260
  const session = new Session({
261
- preset: "chrome-145",
261
+ preset: "chrome-latest",
262
262
  tcpProxy: "http://tcp-proxy:port", // For HTTP/1.1, HTTP/2
263
263
  udpProxy: "https://masque-proxy:port", // For HTTP/3
264
264
  });
@@ -275,7 +275,7 @@ const { Session } = require("httpcloak");
275
275
 
276
276
  // Enable ECH for Cloudflare domains
277
277
  const session = new Session({
278
- preset: "chrome-145",
278
+ preset: "chrome-latest",
279
279
  echConfigDomain: "cloudflare-ech.com",
280
280
  });
281
281
 
@@ -293,7 +293,7 @@ const { Session } = require("httpcloak");
293
293
 
294
294
  // Connect to example.com's IP but request www.cloudflare.com
295
295
  const session = new Session({
296
- preset: "chrome-145",
296
+ preset: "chrome-latest",
297
297
  connectTo: { "www.cloudflare.com": "example.com" },
298
298
  });
299
299
 
@@ -308,7 +308,7 @@ Get HTTP/3 with encrypted SNI through a SOCKS5 proxy:
308
308
  const { Session } = require("httpcloak");
309
309
 
310
310
  const session = new Session({
311
- preset: "chrome-145",
311
+ preset: "chrome-latest",
312
312
  proxy: "socks5h://user:pass@host:port",
313
313
  echConfigDomain: "cloudflare-ech.com",
314
314
  });
@@ -324,18 +324,31 @@ const { Session } = require("httpcloak");
324
324
 
325
325
  const session = new Session();
326
326
 
327
- // Set a cookie
327
+ // Set a simple cookie (global, sent to all domains)
328
328
  session.setCookie("session_id", "abc123");
329
329
 
330
- // Get all cookies
330
+ // Set a domain-scoped cookie with full metadata
331
+ session.setCookie("auth", "token", {
332
+ domain: ".example.com",
333
+ path: "/",
334
+ secure: true,
335
+ httpOnly: true,
336
+ sameSite: "Lax",
337
+ });
338
+
339
+ // Get all cookies (returns Cookie[] with full metadata)
331
340
  const cookies = session.getCookies();
332
- console.log(cookies);
341
+ for (const cookie of cookies) {
342
+ console.log(`${cookie.name}=${cookie.value} (domain: ${cookie.domain})`);
343
+ }
333
344
 
334
- // Access cookies as property
335
- console.log(session.cookies);
345
+ // Get a specific cookie by name (returns Cookie or null)
346
+ const cookie = session.getCookie("session_id");
347
+ if (cookie) console.log(cookie.value);
336
348
 
337
- // Delete a cookie
349
+ // Delete a cookie (omit domain to delete from all domains)
338
350
  session.deleteCookie("session_id");
351
+ session.deleteCookie("auth", ".example.com"); // delete from specific domain
339
352
 
340
353
  // Clear all cookies
341
354
  session.clearCookies();
@@ -349,7 +362,7 @@ session.close();
349
362
  const { Session } = require("httpcloak");
350
363
 
351
364
  const session = new Session({
352
- preset: "chrome-145", // Browser fingerprint preset
365
+ preset: "chrome-latest", // Browser fingerprint preset
353
366
  proxy: null, // Proxy URL
354
367
  tcpProxy: null, // Separate TCP proxy
355
368
  udpProxy: null, // Separate UDP proxy (MASQUE)
@@ -371,8 +384,8 @@ const session = new Session({
371
384
  const { availablePresets } = require("httpcloak");
372
385
 
373
386
  console.log(availablePresets());
374
- // ['chrome-145', 'chrome-144', 'chrome-143', 'chrome-141', 'chrome-133',
375
- // 'firefox-133', 'safari-18', 'chrome-145-ios', ...]
387
+ // ['chrome-146', 'chrome-145', 'chrome-144', 'chrome-143', 'chrome-141', 'chrome-133',
388
+ // 'firefox-133', 'safari-18', 'chrome-146-ios', ...]
376
389
  ```
377
390
 
378
391
  ## Response Object
@@ -428,7 +441,7 @@ stream.close();
428
441
  ```javascript
429
442
  const { Session } = require("httpcloak");
430
443
 
431
- const session = new Session({ preset: "chrome-145" });
444
+ const session = new Session({ preset: "chrome-latest" });
432
445
 
433
446
  // GET
434
447
  const response = await session.get("https://example.com");
@@ -452,9 +465,7 @@ const headResponse = await session.head("https://example.com");
452
465
  const optionsResponse = await session.options("https://example.com");
453
466
 
454
467
  // Custom request
455
- const customResponse = await session.request({
456
- method: "PUT",
457
- url: "https://api.example.com/resource",
468
+ const customResponse = await session.request("PUT", "https://api.example.com/resource", {
458
469
  headers: { "X-Custom": "value" },
459
470
  body: { data: "value" },
460
471
  timeout: 60,
@@ -490,7 +501,7 @@ HTTPCloak includes TypeScript definitions out of the box:
490
501
  ```typescript
491
502
  import { Session, Response, StreamResponse, HTTPCloakError } from "httpcloak";
492
503
 
493
- const session = new Session({ preset: "chrome-145" });
504
+ const session = new Session({ preset: "chrome-latest" });
494
505
 
495
506
  async function fetchData(): Promise<Response> {
496
507
  return session.get("https://example.com");
@@ -519,7 +530,7 @@ const { LocalProxy } = require("httpcloak");
519
530
  const axios = require("axios");
520
531
 
521
532
  // Start local proxy with Chrome fingerprint
522
- const proxy = new LocalProxy({ preset: "chrome-145" });
533
+ const proxy = new LocalProxy({ preset: "chrome-latest" });
523
534
  console.log(`Proxy running on ${proxy.proxyUrl}`);
524
535
 
525
536
  // Use X-HTTPCloak-Scheme header for HTTPS with fingerprinting + streaming
@@ -558,7 +569,7 @@ const { LocalProxy } = require("httpcloak");
558
569
  const axios = require("axios");
559
570
 
560
571
  // Start local proxy with Chrome fingerprint
561
- const proxy = new LocalProxy({ preset: "chrome-145" });
572
+ const proxy = new LocalProxy({ preset: "chrome-latest" });
562
573
 
563
574
  // Standard HTTPS (uses CONNECT tunnel - fingerprinting via upstream proxy only)
564
575
  const response = await axios.get("https://example.com", {
@@ -590,7 +601,7 @@ When your client already provides authentic browser headers, use TLS-only mode:
590
601
  const { LocalProxy } = require("httpcloak");
591
602
 
592
603
  // Only apply TLS fingerprint, pass headers through
593
- const proxy = new LocalProxy({ preset: "chrome-145", tlsOnly: true });
604
+ const proxy = new LocalProxy({ preset: "chrome-latest", tlsOnly: true });
594
605
 
595
606
  // Your client's headers are preserved
596
607
  const response = await fetch("https://example.com", {
@@ -608,10 +619,10 @@ Route different requests through different browser fingerprints:
608
619
  ```javascript
609
620
  const { LocalProxy, Session } = require("httpcloak");
610
621
 
611
- const proxy = new LocalProxy({ preset: "chrome-145" });
622
+ const proxy = new LocalProxy({ preset: "chrome-latest" });
612
623
 
613
624
  // Create sessions with different fingerprints
614
- const chromeSession = new Session({ preset: "chrome-145" });
625
+ const chromeSession = new Session({ preset: "chrome-latest" });
615
626
  const firefoxSession = new Session({ preset: "firefox-133" });
616
627
 
617
628
  // Register sessions with the proxy
@@ -638,7 +649,7 @@ proxy.close();
638
649
  ```javascript
639
650
  const proxy = new LocalProxy({
640
651
  port: 0, // Port (0 = auto-select)
641
- preset: "chrome-145", // Browser fingerprint
652
+ preset: "chrome-latest", // Browser fingerprint
642
653
  timeout: 30, // Request timeout in seconds
643
654
  maxConnections: 1000, // Max concurrent connections
644
655
  tcpProxy: null, // Default upstream TCP proxy
package/lib/index.d.ts CHANGED
@@ -195,7 +195,7 @@ export class StreamResponse {
195
195
  }
196
196
 
197
197
  export interface SessionOptions {
198
- /** Browser preset to use (default: "chrome-145") */
198
+ /** Browser preset to use (default: "chrome-146") */
199
199
  preset?: string;
200
200
  /** Proxy URL (e.g., "http://user:pass@host:port" or "socks5://host:port") */
201
201
  proxy?: string;
@@ -337,22 +337,50 @@ export class Session {
337
337
  options(url: string, options?: RequestOptions): Promise<Response>;
338
338
 
339
339
  // Cookie management
340
- /** Get all cookies from the session */
340
+
341
+ /** Get all cookies with full metadata (domain, path, expiry, flags) */
342
+ getCookiesDetailed(): Cookie[];
343
+
344
+ /** Get a specific cookie by name with full metadata */
345
+ getCookieDetailed(name: string): Cookie | null;
346
+
347
+ /**
348
+ * Get all cookies as a flat name-value object.
349
+ * @deprecated Will return Cookie[] with full metadata in a future release. Use getCookiesDetailed() for the new format now.
350
+ */
341
351
  getCookies(): Record<string, string>;
342
352
 
343
- /** Get a specific cookie by name */
353
+ /**
354
+ * Get a specific cookie value by name.
355
+ * @deprecated Will return Cookie|null in a future release. Use getCookieDetailed() for the new format now.
356
+ */
344
357
  getCookie(name: string): string | null;
345
358
 
346
359
  /** Set a cookie in the session */
347
- setCookie(name: string, value: string): void;
348
-
349
- /** Delete a specific cookie by name */
350
- deleteCookie(name: string): void;
360
+ setCookie(
361
+ name: string,
362
+ value: string,
363
+ options?: {
364
+ domain?: string;
365
+ path?: string;
366
+ secure?: boolean;
367
+ httpOnly?: boolean;
368
+ sameSite?: string;
369
+ maxAge?: number;
370
+ expires?: string;
371
+ }
372
+ ): void;
373
+
374
+ /** Delete a specific cookie by name. If domain is omitted, deletes from all domains. */
375
+ deleteCookie(name: string, domain?: string): void;
351
376
 
352
377
  /** Clear all cookies from the session */
353
378
  clearCookies(): void;
354
379
 
355
- /** Get cookies as a property */
380
+ /**
381
+ * Get cookies as a property.
382
+ * @deprecated Will return Cookie[] with full metadata in a future release.
383
+ */
356
384
  readonly cookies: Record<string, string>;
357
385
 
358
386
  // Proxy management
@@ -619,7 +647,7 @@ export class Session {
619
647
  export interface LocalProxyOptions {
620
648
  /** Port to listen on (default: 0 for auto-assign) */
621
649
  port?: number;
622
- /** Browser preset to use (default: "chrome-145") */
650
+ /** Browser preset to use (default: "chrome-146") */
623
651
  preset?: string;
624
652
  /** Request timeout in seconds (default: 30) */
625
653
  timeout?: number;
@@ -659,7 +687,7 @@ export interface LocalProxyStats {
659
687
  *
660
688
  * @example
661
689
  * // Basic usage
662
- * const proxy = new LocalProxy({ preset: "chrome-145", tlsOnly: true });
690
+ * const proxy = new LocalProxy({ preset: "chrome-146", tlsOnly: true });
663
691
  * console.log(`Proxy running on ${proxy.proxyUrl}`);
664
692
  * // Use with any HTTP client pointing to the proxy
665
693
  * proxy.close();
@@ -816,6 +844,10 @@ export function request(method: string, url: string, options?: RequestOptions):
816
844
 
817
845
  /** Available browser presets */
818
846
  export const Preset: {
847
+ CHROME_146: string;
848
+ CHROME_146_WINDOWS: string;
849
+ CHROME_146_LINUX: string;
850
+ CHROME_146_MACOS: string;
819
851
  CHROME_145: string;
820
852
  CHROME_145_WINDOWS: string;
821
853
  CHROME_145_LINUX: string;
@@ -833,9 +865,11 @@ export const Preset: {
833
865
  CHROME_143_IOS: string;
834
866
  CHROME_144_IOS: string;
835
867
  CHROME_145_IOS: string;
868
+ CHROME_146_IOS: string;
836
869
  CHROME_143_ANDROID: string;
837
870
  CHROME_144_ANDROID: string;
838
871
  CHROME_145_ANDROID: string;
872
+ CHROME_146_ANDROID: string;
839
873
  FIREFOX_133: string;
840
874
  SAFARI_18: string;
841
875
  SAFARI_17_IOS: string;
@@ -844,9 +878,11 @@ export const Preset: {
844
878
  IOS_CHROME_143: string;
845
879
  IOS_CHROME_144: string;
846
880
  IOS_CHROME_145: string;
881
+ IOS_CHROME_146: string;
847
882
  ANDROID_CHROME_143: string;
848
883
  ANDROID_CHROME_144: string;
849
884
  ANDROID_CHROME_145: string;
885
+ ANDROID_CHROME_146: string;
850
886
  IOS_SAFARI_17: string;
851
887
  IOS_SAFARI_18: string;
852
888
  all(): string[];
package/lib/index.js CHANGED
@@ -31,7 +31,13 @@ class HTTPCloakError extends Error {
31
31
  * const session = new httpcloak.Session({ preset: httpcloak.Preset.FIREFOX_133 });
32
32
  */
33
33
  const Preset = {
34
- // Chrome 145 (latest)
34
+ // Chrome 146 (latest)
35
+ CHROME_146: "chrome-146",
36
+ CHROME_146_WINDOWS: "chrome-146-windows",
37
+ CHROME_146_LINUX: "chrome-146-linux",
38
+ CHROME_146_MACOS: "chrome-146-macos",
39
+
40
+ // Chrome 145
35
41
  CHROME_145: "chrome-145",
36
42
  CHROME_145_WINDOWS: "chrome-145-windows",
37
43
  CHROME_145_LINUX: "chrome-145-linux",
@@ -59,9 +65,11 @@ const Preset = {
59
65
  CHROME_143_IOS: "chrome-143-ios",
60
66
  CHROME_144_IOS: "chrome-144-ios",
61
67
  CHROME_145_IOS: "chrome-145-ios",
68
+ CHROME_146_IOS: "chrome-146-ios",
62
69
  CHROME_143_ANDROID: "chrome-143-android",
63
70
  CHROME_144_ANDROID: "chrome-144-android",
64
71
  CHROME_145_ANDROID: "chrome-145-android",
72
+ CHROME_146_ANDROID: "chrome-146-android",
65
73
 
66
74
  // Firefox
67
75
  FIREFOX_133: "firefox-133",
@@ -75,9 +83,11 @@ const Preset = {
75
83
  IOS_CHROME_143: "chrome-143-ios",
76
84
  IOS_CHROME_144: "chrome-144-ios",
77
85
  IOS_CHROME_145: "chrome-145-ios",
86
+ IOS_CHROME_146: "chrome-146-ios",
78
87
  ANDROID_CHROME_143: "chrome-143-android",
79
88
  ANDROID_CHROME_144: "chrome-144-android",
80
89
  ANDROID_CHROME_145: "chrome-145-android",
90
+ ANDROID_CHROME_146: "chrome-146-android",
81
91
  IOS_SAFARI_17: "safari-17-ios",
82
92
  IOS_SAFARI_18: "safari-18-ios",
83
93
 
@@ -87,12 +97,13 @@ const Preset = {
87
97
  */
88
98
  all() {
89
99
  return [
100
+ this.CHROME_146, this.CHROME_146_WINDOWS, this.CHROME_146_LINUX, this.CHROME_146_MACOS,
90
101
  this.CHROME_145, this.CHROME_145_WINDOWS, this.CHROME_145_LINUX, this.CHROME_145_MACOS,
91
102
  this.CHROME_144, this.CHROME_144_WINDOWS, this.CHROME_144_LINUX, this.CHROME_144_MACOS,
92
103
  this.CHROME_143, this.CHROME_143_WINDOWS, this.CHROME_143_LINUX, this.CHROME_143_MACOS,
93
104
  this.CHROME_141, this.CHROME_133,
94
- this.CHROME_145_IOS, this.CHROME_144_IOS, this.CHROME_143_IOS,
95
- this.CHROME_145_ANDROID, this.CHROME_144_ANDROID, this.CHROME_143_ANDROID,
105
+ this.CHROME_146_IOS, this.CHROME_145_IOS, this.CHROME_144_IOS, this.CHROME_143_IOS,
106
+ this.CHROME_146_ANDROID, this.CHROME_145_ANDROID, this.CHROME_144_ANDROID, this.CHROME_143_ANDROID,
96
107
  this.FIREFOX_133,
97
108
  this.SAFARI_18, this.SAFARI_17_IOS, this.SAFARI_18_IOS,
98
109
  ];
@@ -789,7 +800,9 @@ function getLib() {
789
800
  httpcloak_post: nativeLibHandle.func("httpcloak_post", "str", ["int64", "str", "str", "str"]),
790
801
  httpcloak_request: nativeLibHandle.func("httpcloak_request", "str", ["int64", "str"]),
791
802
  httpcloak_get_cookies: nativeLibHandle.func("httpcloak_get_cookies", "str", ["int64"]),
792
- httpcloak_set_cookie: nativeLibHandle.func("httpcloak_set_cookie", "void", ["int64", "str", "str"]),
803
+ httpcloak_set_cookie: nativeLibHandle.func("httpcloak_set_cookie", "void", ["int64", "str"]),
804
+ httpcloak_delete_cookie: nativeLibHandle.func("httpcloak_delete_cookie", "void", ["int64", "str", "str"]),
805
+ httpcloak_clear_cookies: nativeLibHandle.func("httpcloak_clear_cookies", "void", ["int64"]),
793
806
  httpcloak_free_string: nativeLibHandle.func("httpcloak_free_string", "void", ["void*"]),
794
807
  httpcloak_version: nativeLibHandle.func("httpcloak_version", "str", []),
795
808
  httpcloak_available_presets: nativeLibHandle.func("httpcloak_available_presets", "str", []),
@@ -1162,7 +1175,7 @@ function version() {
1162
1175
  /**
1163
1176
  * Get available browser presets with their supported protocols.
1164
1177
  * Returns an object mapping preset names to their info:
1165
- * { "chrome-145": { protocols: ["h1", "h2", "h3"] }, ... }
1178
+ * { "chrome-146": { protocols: ["h1", "h2", "h3"] }, ... }
1166
1179
  */
1167
1180
  function availablePresets() {
1168
1181
  const nativeLib = getLib();
@@ -1228,7 +1241,7 @@ class Session {
1228
1241
  /**
1229
1242
  * Create a new session
1230
1243
  * @param {Object} options - Session options
1231
- * @param {string} [options.preset="chrome-145"] - Browser preset to use
1244
+ * @param {string} [options.preset="chrome-146"] - Browser preset to use
1232
1245
  * @param {string} [options.proxy] - Proxy URL (e.g., "http://user:pass@host:port" or "socks5://host:port")
1233
1246
  * @param {string} [options.tcpProxy] - Proxy URL for TCP protocols (HTTP/1.1, HTTP/2) - use with udpProxy for split config
1234
1247
  * @param {string} [options.udpProxy] - Proxy URL for UDP protocols (HTTP/3 via MASQUE) - use with tcpProxy for split config
@@ -1249,7 +1262,7 @@ class Session {
1249
1262
  */
1250
1263
  constructor(options = {}) {
1251
1264
  const {
1252
- preset = "chrome-145",
1265
+ preset = "chrome-146",
1253
1266
  proxy = null,
1254
1267
  tcpProxy = null,
1255
1268
  udpProxy = null,
@@ -1275,6 +1288,11 @@ class Session {
1275
1288
  ja3 = null,
1276
1289
  akamai = null,
1277
1290
  extraFp = null,
1291
+ tcpTtl = null,
1292
+ tcpMss = null,
1293
+ tcpWindowSize = null,
1294
+ tcpWindowScale = null,
1295
+ tcpDf = null,
1278
1296
  } = options;
1279
1297
 
1280
1298
  this._lib = getLib();
@@ -1350,6 +1368,21 @@ class Session {
1350
1368
  if (extraFp) {
1351
1369
  config.extra_fp = extraFp;
1352
1370
  }
1371
+ if (tcpTtl != null) {
1372
+ config.tcp_ttl = tcpTtl;
1373
+ }
1374
+ if (tcpMss != null) {
1375
+ config.tcp_mss = tcpMss;
1376
+ }
1377
+ if (tcpWindowSize != null) {
1378
+ config.tcp_window_size = tcpWindowSize;
1379
+ }
1380
+ if (tcpWindowScale != null) {
1381
+ config.tcp_window_scale = tcpWindowScale;
1382
+ }
1383
+ if (tcpDf != null) {
1384
+ config.tcp_df = tcpDf;
1385
+ }
1353
1386
 
1354
1387
  this._handle = this._lib.httpcloak_session_new(JSON.stringify(config));
1355
1388
 
@@ -1855,58 +1888,118 @@ class Session {
1855
1888
  // ===========================================================================
1856
1889
 
1857
1890
  /**
1858
- * Get all cookies from the session
1859
- * @returns {Object} Cookies as key-value pairs
1891
+ * Get all cookies with full metadata (domain, path, expiry, flags).
1892
+ * @returns {Cookie[]} Array of Cookie objects
1860
1893
  */
1861
- getCookies() {
1894
+ getCookiesDetailed() {
1862
1895
  const resultPtr = this._lib.httpcloak_get_cookies(this._handle);
1863
1896
  const result = resultToString(resultPtr);
1864
1897
  if (result) {
1865
- return JSON.parse(result);
1898
+ const parsed = JSON.parse(result);
1899
+ return parsed.map(c => new Cookie(c));
1866
1900
  }
1867
- return {};
1901
+ return [];
1902
+ }
1903
+
1904
+ /**
1905
+ * Get all cookies as a flat name-value object.
1906
+ * @deprecated getCookies() will return Cookie[] with full metadata (domain, path, expiry) in a future release.
1907
+ * Use getCookiesDetailed() if you want the new format now.
1908
+ * @returns {Object} Cookies as key-value pairs
1909
+ */
1910
+ getCookies() {
1911
+ if (!Session._getCookiesDeprecated) {
1912
+ Session._getCookiesDeprecated = true;
1913
+ process.emitWarning(
1914
+ 'getCookies() currently returns a flat {name: value} object. In a future release, it will return Cookie[] with full metadata (domain, path, expiry, etc.), same as getCookiesDetailed(). Update your code accordingly.',
1915
+ 'DeprecationWarning'
1916
+ );
1917
+ }
1918
+ const cookies = this.getCookiesDetailed();
1919
+ const result = {};
1920
+ for (const c of cookies) {
1921
+ result[c.name] = c.value;
1922
+ }
1923
+ return result;
1924
+ }
1925
+
1926
+ /**
1927
+ * Get a specific cookie by name with full metadata.
1928
+ * @param {string} name - Cookie name
1929
+ * @returns {Cookie|null} Cookie object or null if not found
1930
+ */
1931
+ getCookieDetailed(name) {
1932
+ const cookies = this.getCookiesDetailed();
1933
+ return cookies.find(c => c.name === name) || null;
1868
1934
  }
1869
1935
 
1870
1936
  /**
1871
- * Get a specific cookie by name
1937
+ * Get a specific cookie value by name.
1938
+ * @deprecated getCookie() will return a Cookie object (with domain, path, expiry) instead of a string in a future release.
1939
+ * Use getCookieDetailed() if you want the new format now.
1872
1940
  * @param {string} name - Cookie name
1873
1941
  * @returns {string|null} Cookie value or null if not found
1874
1942
  */
1875
1943
  getCookie(name) {
1876
- const cookies = this.getCookies();
1877
- return cookies[name] || null;
1944
+ if (!Session._getCookieDeprecated) {
1945
+ Session._getCookieDeprecated = true;
1946
+ process.emitWarning(
1947
+ 'getCookie() currently returns a string value. In a future release, it will return a Cookie object with full metadata (domain, path, expiry, etc.), same as getCookieDetailed(). Update your code accordingly.',
1948
+ 'DeprecationWarning'
1949
+ );
1950
+ }
1951
+ const cookie = this.getCookieDetailed(name);
1952
+ return cookie ? cookie.value : null;
1878
1953
  }
1879
1954
 
1880
1955
  /**
1881
1956
  * Set a cookie in the session
1882
1957
  * @param {string} name - Cookie name
1883
1958
  * @param {string} value - Cookie value
1884
- */
1885
- setCookie(name, value) {
1886
- this._lib.httpcloak_set_cookie(this._handle, name, value);
1959
+ * @param {Object} [options] - Cookie options
1960
+ * @param {string} [options.domain] - Cookie domain
1961
+ * @param {string} [options.path] - Cookie path (default: "/")
1962
+ * @param {boolean} [options.secure] - Secure flag
1963
+ * @param {boolean} [options.httpOnly] - HttpOnly flag
1964
+ * @param {string} [options.sameSite] - SameSite attribute (Strict, Lax, None)
1965
+ * @param {number} [options.maxAge] - Max age in seconds (0 means not set)
1966
+ * @param {string} [options.expires] - Expiration date (RFC1123 format)
1967
+ */
1968
+ setCookie(name, value, options = {}) {
1969
+ const cookie = {
1970
+ name,
1971
+ value,
1972
+ domain: options.domain || "",
1973
+ path: options.path || "/",
1974
+ secure: options.secure || false,
1975
+ http_only: options.httpOnly || false,
1976
+ same_site: options.sameSite || "",
1977
+ max_age: options.maxAge || 0,
1978
+ expires: options.expires || "",
1979
+ };
1980
+ this._lib.httpcloak_set_cookie(this._handle, JSON.stringify(cookie));
1887
1981
  }
1888
1982
 
1889
1983
  /**
1890
1984
  * Delete a specific cookie by name
1891
1985
  * @param {string} name - Cookie name to delete
1986
+ * @param {string} [domain] - Domain to delete from (omit to delete from all domains)
1892
1987
  */
1893
- deleteCookie(name) {
1894
- // Set cookie to empty value - effectively deletes it
1895
- this._lib.httpcloak_set_cookie(this._handle, name, "");
1988
+ deleteCookie(name, domain = "") {
1989
+ this._lib.httpcloak_delete_cookie(this._handle, name, domain);
1896
1990
  }
1897
1991
 
1898
1992
  /**
1899
1993
  * Clear all cookies from the session
1900
1994
  */
1901
1995
  clearCookies() {
1902
- const cookies = this.getCookies();
1903
- for (const name of Object.keys(cookies)) {
1904
- this.deleteCookie(name);
1905
- }
1996
+ this._lib.httpcloak_clear_cookies(this._handle);
1906
1997
  }
1907
1998
 
1908
1999
  /**
1909
- * Get cookies as a property
2000
+ * Get cookies as a property.
2001
+ * @deprecated This property will return Cookie[] with full metadata in a future release.
2002
+ * @returns {Object} Cookies as key-value pairs
1910
2003
  */
1911
2004
  get cookies() {
1912
2005
  return this.getCookies();
@@ -2077,7 +2170,7 @@ class Session {
2077
2170
  * @param {string} path - Path to save the session file
2078
2171
  *
2079
2172
  * Example:
2080
- * const session = new httpcloak.Session({ preset: "chrome-145" });
2173
+ * const session = new httpcloak.Session({ preset: "chrome-146" });
2081
2174
  * await session.get("https://example.com"); // Acquire cookies
2082
2175
  * session.save("session.json");
2083
2176
  *
@@ -2715,7 +2808,7 @@ let _defaultConfig = {};
2715
2808
  /**
2716
2809
  * Configure defaults for module-level functions
2717
2810
  * @param {Object} options - Configuration options
2718
- * @param {string} [options.preset="chrome-145"] - Browser preset
2811
+ * @param {string} [options.preset="chrome-146"] - Browser preset
2719
2812
  * @param {Object} [options.headers] - Default headers
2720
2813
  * @param {Array} [options.auth] - Default basic auth [username, password]
2721
2814
  * @param {string} [options.proxy] - Proxy URL
@@ -2729,7 +2822,7 @@ let _defaultConfig = {};
2729
2822
  */
2730
2823
  function configure(options = {}) {
2731
2824
  const {
2732
- preset = "chrome-145",
2825
+ preset = "chrome-146",
2733
2826
  headers = null,
2734
2827
  auth = null,
2735
2828
  proxy = null,
@@ -2787,7 +2880,7 @@ function configure(options = {}) {
2787
2880
  */
2788
2881
  function _getDefaultSession() {
2789
2882
  if (!_defaultSession) {
2790
- const preset = _defaultConfig.preset || "chrome-145";
2883
+ const preset = _defaultConfig.preset || "chrome-146";
2791
2884
  const proxy = _defaultConfig.proxy || null;
2792
2885
  const timeout = _defaultConfig.timeout || 30;
2793
2886
  const httpVersion = _defaultConfig.httpVersion || "auto";
@@ -2890,7 +2983,7 @@ function request(method, url, options = {}) {
2890
2983
  * Without registration, cache callbacks will not be triggered for that session.
2891
2984
  *
2892
2985
  * @example
2893
- * const proxy = new LocalProxy({ preset: "chrome-145", tlsOnly: true });
2986
+ * const proxy = new LocalProxy({ preset: "chrome-146", tlsOnly: true });
2894
2987
  * console.log(`Proxy running on ${proxy.proxyUrl}`);
2895
2988
  *
2896
2989
  * // Use with any HTTP client pointing to the proxy
@@ -2919,7 +3012,7 @@ class LocalProxy {
2919
3012
  * Create and start a local HTTP proxy server.
2920
3013
  * @param {Object} options - Proxy configuration options
2921
3014
  * @param {number} [options.port=0] - Port to listen on (0 = auto-select)
2922
- * @param {string} [options.preset="chrome-145"] - Browser fingerprint preset
3015
+ * @param {string} [options.preset="chrome-146"] - Browser fingerprint preset
2923
3016
  * @param {number} [options.timeout=30] - Request timeout in seconds
2924
3017
  * @param {number} [options.maxConnections=1000] - Maximum concurrent connections
2925
3018
  * @param {string} [options.tcpProxy] - Default upstream TCP proxy URL
@@ -2929,7 +3022,7 @@ class LocalProxy {
2929
3022
  constructor(options = {}) {
2930
3023
  const {
2931
3024
  port = 0,
2932
- preset = "chrome-145",
3025
+ preset = "chrome-146",
2933
3026
  timeout = 30,
2934
3027
  maxConnections = 1000,
2935
3028
  tcpProxy = null,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/darwin-arm64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for darwin arm64",
5
5
  "os": [
6
6
  "darwin"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/darwin-x64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for darwin x64",
5
5
  "os": [
6
6
  "darwin"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/linux-arm64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for linux arm64",
5
5
  "os": [
6
6
  "linux"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/linux-x64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for linux x64",
5
5
  "os": [
6
6
  "linux"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/win32-arm64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for win32 arm64",
5
5
  "os": [
6
6
  "win32"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/win32-x64",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "HTTPCloak native binary for win32 x64",
5
5
  "os": [
6
6
  "win32"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "httpcloak",
3
- "version": "1.6.1-beta.2",
3
+ "version": "1.6.1",
4
4
  "description": "Browser fingerprint emulation HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -49,12 +49,12 @@
49
49
  "koffi": "^2.9.0"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@httpcloak/darwin-arm64": "1.6.1-beta.2",
53
- "@httpcloak/darwin-x64": "1.6.1-beta.2",
54
- "@httpcloak/linux-arm64": "1.6.1-beta.2",
55
- "@httpcloak/linux-x64": "1.6.1-beta.2",
56
- "@httpcloak/win32-arm64": "1.6.1-beta.2",
57
- "@httpcloak/win32-x64": "1.6.1-beta.2"
52
+ "@httpcloak/darwin-arm64": "1.6.1",
53
+ "@httpcloak/darwin-x64": "1.6.1",
54
+ "@httpcloak/linux-arm64": "1.6.1",
55
+ "@httpcloak/linux-x64": "1.6.1",
56
+ "@httpcloak/win32-arm64": "1.6.1",
57
+ "@httpcloak/win32-x64": "1.6.1"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^25.1.0",