httpcloak 1.6.1-beta.3 → 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,
@@ -1279,6 +1292,7 @@ class Session {
1279
1292
  tcpMss = null,
1280
1293
  tcpWindowSize = null,
1281
1294
  tcpWindowScale = null,
1295
+ tcpDf = null,
1282
1296
  } = options;
1283
1297
 
1284
1298
  this._lib = getLib();
@@ -1366,6 +1380,9 @@ class Session {
1366
1380
  if (tcpWindowScale != null) {
1367
1381
  config.tcp_window_scale = tcpWindowScale;
1368
1382
  }
1383
+ if (tcpDf != null) {
1384
+ config.tcp_df = tcpDf;
1385
+ }
1369
1386
 
1370
1387
  this._handle = this._lib.httpcloak_session_new(JSON.stringify(config));
1371
1388
 
@@ -1871,58 +1888,118 @@ class Session {
1871
1888
  // ===========================================================================
1872
1889
 
1873
1890
  /**
1874
- * Get all cookies from the session
1875
- * @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
1876
1893
  */
1877
- getCookies() {
1894
+ getCookiesDetailed() {
1878
1895
  const resultPtr = this._lib.httpcloak_get_cookies(this._handle);
1879
1896
  const result = resultToString(resultPtr);
1880
1897
  if (result) {
1881
- return JSON.parse(result);
1898
+ const parsed = JSON.parse(result);
1899
+ return parsed.map(c => new Cookie(c));
1882
1900
  }
1883
- 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;
1884
1934
  }
1885
1935
 
1886
1936
  /**
1887
- * 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.
1888
1940
  * @param {string} name - Cookie name
1889
1941
  * @returns {string|null} Cookie value or null if not found
1890
1942
  */
1891
1943
  getCookie(name) {
1892
- const cookies = this.getCookies();
1893
- 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;
1894
1953
  }
1895
1954
 
1896
1955
  /**
1897
1956
  * Set a cookie in the session
1898
1957
  * @param {string} name - Cookie name
1899
1958
  * @param {string} value - Cookie value
1900
- */
1901
- setCookie(name, value) {
1902
- 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));
1903
1981
  }
1904
1982
 
1905
1983
  /**
1906
1984
  * Delete a specific cookie by name
1907
1985
  * @param {string} name - Cookie name to delete
1986
+ * @param {string} [domain] - Domain to delete from (omit to delete from all domains)
1908
1987
  */
1909
- deleteCookie(name) {
1910
- // Set cookie to empty value - effectively deletes it
1911
- this._lib.httpcloak_set_cookie(this._handle, name, "");
1988
+ deleteCookie(name, domain = "") {
1989
+ this._lib.httpcloak_delete_cookie(this._handle, name, domain);
1912
1990
  }
1913
1991
 
1914
1992
  /**
1915
1993
  * Clear all cookies from the session
1916
1994
  */
1917
1995
  clearCookies() {
1918
- const cookies = this.getCookies();
1919
- for (const name of Object.keys(cookies)) {
1920
- this.deleteCookie(name);
1921
- }
1996
+ this._lib.httpcloak_clear_cookies(this._handle);
1922
1997
  }
1923
1998
 
1924
1999
  /**
1925
- * 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
1926
2003
  */
1927
2004
  get cookies() {
1928
2005
  return this.getCookies();
@@ -2093,7 +2170,7 @@ class Session {
2093
2170
  * @param {string} path - Path to save the session file
2094
2171
  *
2095
2172
  * Example:
2096
- * const session = new httpcloak.Session({ preset: "chrome-145" });
2173
+ * const session = new httpcloak.Session({ preset: "chrome-146" });
2097
2174
  * await session.get("https://example.com"); // Acquire cookies
2098
2175
  * session.save("session.json");
2099
2176
  *
@@ -2731,7 +2808,7 @@ let _defaultConfig = {};
2731
2808
  /**
2732
2809
  * Configure defaults for module-level functions
2733
2810
  * @param {Object} options - Configuration options
2734
- * @param {string} [options.preset="chrome-145"] - Browser preset
2811
+ * @param {string} [options.preset="chrome-146"] - Browser preset
2735
2812
  * @param {Object} [options.headers] - Default headers
2736
2813
  * @param {Array} [options.auth] - Default basic auth [username, password]
2737
2814
  * @param {string} [options.proxy] - Proxy URL
@@ -2745,7 +2822,7 @@ let _defaultConfig = {};
2745
2822
  */
2746
2823
  function configure(options = {}) {
2747
2824
  const {
2748
- preset = "chrome-145",
2825
+ preset = "chrome-146",
2749
2826
  headers = null,
2750
2827
  auth = null,
2751
2828
  proxy = null,
@@ -2803,7 +2880,7 @@ function configure(options = {}) {
2803
2880
  */
2804
2881
  function _getDefaultSession() {
2805
2882
  if (!_defaultSession) {
2806
- const preset = _defaultConfig.preset || "chrome-145";
2883
+ const preset = _defaultConfig.preset || "chrome-146";
2807
2884
  const proxy = _defaultConfig.proxy || null;
2808
2885
  const timeout = _defaultConfig.timeout || 30;
2809
2886
  const httpVersion = _defaultConfig.httpVersion || "auto";
@@ -2906,7 +2983,7 @@ function request(method, url, options = {}) {
2906
2983
  * Without registration, cache callbacks will not be triggered for that session.
2907
2984
  *
2908
2985
  * @example
2909
- * const proxy = new LocalProxy({ preset: "chrome-145", tlsOnly: true });
2986
+ * const proxy = new LocalProxy({ preset: "chrome-146", tlsOnly: true });
2910
2987
  * console.log(`Proxy running on ${proxy.proxyUrl}`);
2911
2988
  *
2912
2989
  * // Use with any HTTP client pointing to the proxy
@@ -2935,7 +3012,7 @@ class LocalProxy {
2935
3012
  * Create and start a local HTTP proxy server.
2936
3013
  * @param {Object} options - Proxy configuration options
2937
3014
  * @param {number} [options.port=0] - Port to listen on (0 = auto-select)
2938
- * @param {string} [options.preset="chrome-145"] - Browser fingerprint preset
3015
+ * @param {string} [options.preset="chrome-146"] - Browser fingerprint preset
2939
3016
  * @param {number} [options.timeout=30] - Request timeout in seconds
2940
3017
  * @param {number} [options.maxConnections=1000] - Maximum concurrent connections
2941
3018
  * @param {string} [options.tcpProxy] - Default upstream TCP proxy URL
@@ -2945,7 +3022,7 @@ class LocalProxy {
2945
3022
  constructor(options = {}) {
2946
3023
  const {
2947
3024
  port = 0,
2948
- preset = "chrome-145",
3025
+ preset = "chrome-146",
2949
3026
  timeout = 30,
2950
3027
  maxConnections = 1000,
2951
3028
  tcpProxy = null,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@httpcloak/darwin-arm64",
3
- "version": "1.6.1-beta.3",
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.3",
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.3",
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.3",
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.3",
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.3",
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.3",
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.3",
53
- "@httpcloak/darwin-x64": "1.6.1-beta.3",
54
- "@httpcloak/linux-arm64": "1.6.1-beta.3",
55
- "@httpcloak/linux-x64": "1.6.1-beta.3",
56
- "@httpcloak/win32-arm64": "1.6.1-beta.3",
57
- "@httpcloak/win32-x64": "1.6.1-beta.3"
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",