@mks2508/binary-cookies-parser 1.0.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -1 +1,2 @@
1
- var D=Object.create;var{getPrototypeOf:O,defineProperty:M,getOwnPropertyNames:Z,getOwnPropertyDescriptor:S}=Object,_=Object.prototype.hasOwnProperty;var B=(E,q,F)=>{F=E!=null?D(O(E)):{};let G=q||!E||!E.__esModule?M(F,"default",{value:E,enumerable:!0}):F;for(let L of Z(E))if(!_.call(G,L))M(G,L,{get:()=>E[L],enumerable:!0});return G},Y=new WeakMap,m=(E)=>{var q=Y.get(E),F;if(q)return q;if(q=M({},"__esModule",{value:!0}),E&&typeof E==="object"||typeof E==="function")Z(E).map((G)=>!_.call(q,G)&&M(q,G,{get:()=>E[G],enumerable:!(F=S(E,G))||F.enumerable}));return Y.set(E,q),q};var C=(E,q)=>{for(var F in q)M(E,F,{get:q[F],enumerable:!0,configurable:!0,set:(G)=>q[F]=()=>G})};var x={};C(x,{parseBinaryCookies:()=>I,BinaryCookiesParser:()=>U});module.exports=m(x);var $=B(require("node:fs/promises")),w=require("node:fs");class U{cookiePath=null;currentBufferPosition=0;data=null;numPages=0;bufferSize=0;pages=[];pageSizes=[];cookies=[];async parse(E){if(this.reset(),this.cookiePath=E,!w.existsSync(E))throw Error(`Cookie file not found: ${E}`);await this.openFile(),this.getNumPages(),this.getPageSizes(),this.getPages();for(let q=0;q<this.pages.length;q++){this.getNumCookies(q),this.getCookieOffsets(q),this.getCookieData(q);for(let F=0;F<this.pages[q].cookies.length;F++){let G=this.parseCookieData(q,F);this.cookies.push(G)}}return this.cookies}reset(){this.cookiePath=null,this.currentBufferPosition=0,this.data=null,this.numPages=0,this.bufferSize=0,this.pages=[],this.pageSizes=[],this.cookies=[]}async openFile(){if(!this.cookiePath)throw Error("Cookie path not set");let E=await $.default.readFile(this.cookiePath);if(this.data=E,this.bufferSize=E.length,this.readSlice(4).toString()!=="cook")throw Error('Invalid binary cookies file format (missing "cook" header)')}readSlice(E){if(!this.data)throw Error("No data loaded");let q=this.data.subarray(this.currentBufferPosition,this.currentBufferPosition+E);return this.currentBufferPosition+=E,q}readIntBE(){if(!this.data)throw Error("No data loaded");let E=this.data.readInt32BE(this.currentBufferPosition);return this.currentBufferPosition+=4,E}readIntLE(){if(!this.data)throw Error("No data loaded");let E=this.data.readInt32LE(this.currentBufferPosition);return this.currentBufferPosition+=4,E}getNumPages(){return this.numPages=this.readIntBE(),this.numPages}getPageSizes(){for(let E=0;E<this.numPages;E++)this.pageSizes.push(this.readIntBE());return this.pageSizes}getPages(){for(let E of this.pageSizes)this.pages.push({buffer:this.readSlice(E),bufferPosition:0,numCookies:0,cookieOffsets:[],cookies:[]});return this.pages}getNumCookies(E){let q=this.pages[E];q.bufferPosition=0;let F=q.buffer.readInt32BE(q.bufferPosition);if(q.bufferPosition+=4,F!==256)throw Error(`Invalid page header: expected 256, got ${F}`);return q.numCookies=q.buffer.readInt32LE(q.bufferPosition),q.bufferPosition+=4,q.numCookies}getCookieOffsets(E){let q=this.pages[E];q.cookieOffsets=[];for(let F=0;F<q.numCookies;F++)q.cookieOffsets.push(q.buffer.readInt32LE(q.bufferPosition)),q.bufferPosition+=4;return q.cookieOffsets}getCookieData(E){let q=this.pages[E];q.cookies=[];for(let F of q.cookieOffsets){let G=q.buffer.readInt32LE(F);try{q.cookies.push({buffer:q.buffer.subarray(F,F+G)})}catch{q.cookies.push({buffer:q.buffer.subarray(F)})}}return q.cookies}parseCookieData(E,q){let L=this.pages[E].cookies[q].buffer,y=978307200,J=0,l=L.readInt32LE(J);J+=4;let K=L.readInt32LE(J);J+=8;let d=L.readUInt32LE(J),V={},z=["url","name","path","value"];for(let N of z)J+=4,V[N]=L.readInt32LE(J);J+=4;let h=L.readUInt32LE(J);J+=8;let A=L.readDoubleLE(J)+978307200,H=new Date(A*1000);J+=8;let T=L.readDoubleLE(J)+978307200,j=new Date(T*1000),W={flags:K,expiration:H,creation:j};for(let[N,v]of Object.entries(V)){let X="",Q=v,R="";do R=L.toString("utf8",Q,Q+1),X+=R,Q++;while(R!=="\x00");W[N]=X.replace(/\u0000/g,"").trim()}return W}}async function I(E){return new U().parse(E)}
1
+ var{defineProperty:V,getOwnPropertyNames:Y,getOwnPropertyDescriptor:Z}=Object,_=Object.prototype.hasOwnProperty;var W=new WeakMap,$=(E)=>{var q=W.get(E),G;if(q)return q;if(q=V({},"__esModule",{value:!0}),E&&typeof E==="object"||typeof E==="function")Y(E).map((K)=>!_.call(q,K)&&V(q,K,{get:()=>E[K],enumerable:!(G=Z(E,K))||G.enumerable}));return W.set(E,q),q};var j=(E,q)=>{for(var G in q)V(E,G,{get:q[G],enumerable:!0,configurable:!0,set:(K)=>q[G]=()=>K})};var J={};j(J,{tryDetectFormat:()=>R.tryDetectFormat,toNetscapeFormat:()=>x,toJSONFormat:()=>H,toCookieHeader:()=>P,parseNetscape:()=>M.parseNetscape,parseJSON:()=>Q.parseJSON,parseCookies:()=>w,parseBinaryToUniversal:()=>I.parseBinaryToUniversal,parseBinaryCookies:()=>I.parseBinaryCookies,isNetscapeFormat:()=>M.isNetscapeFormat,isJSONFormat:()=>Q.isJSONFormat,isBinaryFormat:()=>I.isBinaryFormat,filterExpired:()=>g,filterByDomain:()=>A,detectFormat:()=>R.detectFormat,binaryToUniversal:()=>I.binaryToUniversal,BinaryCookiesParser:()=>I.BinaryCookiesParser});module.exports=$(J);var M=require("./parsers/netscape"),Q=require("./parsers/json"),I=require("./parsers/binary"),R=require("./detector");function w(E){let q=R.detectFormat(E);switch(q){case"netscape":return{format:q,cookies:M.parseNetscape(E)};case"json":return{format:q,cookies:Q.parseJSON(Buffer.isBuffer(E)?E.toString("utf8"):E)};case"binary":return{format:q,cookies:I.parseBinaryToUniversal(Buffer.isBuffer(E)?E:Buffer.from(E))}}}function A(E,q){let G=q.toLowerCase();return E.filter((K)=>{let L=K.domain.toLowerCase();if(L===G)return!0;if(G.startsWith("."))return L===G||L.endsWith(G);return L===G||L===`.${G}`||L.endsWith(`.${G}`)})}function g(E){let q=new Date;return E.filter((G)=>{if(!G.expires)return!0;return G.expires>q})}function x(E){let q=["# Netscape HTTP Cookie File"];for(let G of E){let K=G.domain.startsWith(".")?"TRUE":"FALSE",L=G.secure?"TRUE":"FALSE",X=G.expires?Math.floor(G.expires.getTime()/1000):0;q.push([G.domain,K,G.path,L,X,G.name,G.value].join("\t"))}return q.join(`
2
+ `)}function H(E){return JSON.stringify(E.map((q)=>({name:q.name,value:q.value,domain:q.domain,path:q.path,secure:q.secure,httpOnly:q.httpOnly,...q.expires&&{expirationDate:Math.floor(q.expires.getTime()/1000)},...q.sameSite&&{sameSite:q.sameSite.toLowerCase()}})),null,2)}function P(E){return E.map((q)=>`${q.name}=${q.value}`).join("; ")}
@@ -0,0 +1,29 @@
1
+ import type { CookieFormat } from './types';
2
+ /**
3
+ * Auto-detect the format of cookie data
4
+ *
5
+ * Detection order:
6
+ * 1. Binary format: Buffer starting with 'cook' magic bytes
7
+ * 2. JSON format: String starting with '{' or '['
8
+ * 3. Netscape format: Tab-separated values with TRUE/FALSE flags
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { detectFormat } from '@mks2508/binary-cookies-parser';
13
+ *
14
+ * const format = detectFormat('.youtube.com\tTRUE\t/\tTRUE\t0\tSID\tabc');
15
+ * console.log(format); // 'netscape'
16
+ * ```
17
+ *
18
+ * @param content - String or Buffer containing cookie data
19
+ * @returns Detected format type
20
+ * @throws {Error} If format cannot be detected
21
+ */
22
+ export declare function detectFormat(content: string | Buffer): CookieFormat;
23
+ /**
24
+ * Try to detect the format without throwing
25
+ *
26
+ * @param content - String or Buffer containing cookie data
27
+ * @returns Detected format or null if detection fails
28
+ */
29
+ export declare function tryDetectFormat(content: string | Buffer): CookieFormat | null;
package/dist/index.d.ts CHANGED
@@ -1,68 +1,93 @@
1
- import type { BinaryCookie } from './types';
2
- export type { BinaryCookie, CookiePage } from './types';
1
+ import { parseNetscape, isNetscapeFormat } from './parsers/netscape';
2
+ import { parseJSON, isJSONFormat } from './parsers/json';
3
+ import { BinaryCookiesParser, parseBinaryCookies, parseBinaryToUniversal, binaryToUniversal, isBinaryFormat } from './parsers/binary';
4
+ import { detectFormat, tryDetectFormat } from './detector';
5
+ import type { UniversalCookie, CookieFormat, ParseResult, BinaryCookie, CookiePage } from './types';
6
+ export type { UniversalCookie, CookieFormat, ParseResult, BinaryCookie, CookiePage };
7
+ export { parseNetscape, isNetscapeFormat, parseJSON, isJSONFormat, BinaryCookiesParser, parseBinaryCookies, parseBinaryToUniversal, binaryToUniversal, isBinaryFormat, detectFormat, tryDetectFormat };
3
8
  /**
4
- * Parser for macOS binary cookies files (.binarycookies)
9
+ * Parse cookies from any supported format with auto-detection
5
10
  *
6
- * These files are used by Safari and other macOS applications to store cookies
7
- * in a binary format that's more efficient than plain text.
11
+ * Supports:
12
+ * - Netscape/Mozilla cookies.txt format (used by yt-dlp, browsers)
13
+ * - JSON format (Chrome extensions, various exporters)
14
+ * - Binary Safari format (.binarycookies files)
8
15
  *
9
16
  * @example
10
17
  * ```typescript
11
- * import { BinaryCookiesParser } from 'binary-cookies-parser';
18
+ * import { parseCookies } from '@mks2508/binary-cookies-parser';
12
19
  *
13
- * const parser = new BinaryCookiesParser();
14
- * const cookies = await parser.parse('/path/to/Cookies.binarycookies');
15
- * console.log(cookies);
20
+ * // Auto-detect and parse
21
+ * const netscape = parseCookies('.youtube.com\tTRUE\t/\tTRUE\t0\tSID\tabc');
22
+ * const json = parseCookies('[{"name":"SID","value":"abc","domain":".youtube.com"}]');
23
+ * const binary = parseCookies(binaryBuffer);
16
24
  * ```
25
+ *
26
+ * @param content - Cookie data as string or Buffer
27
+ * @returns ParseResult with detected format and array of cookies
28
+ * @throws {Error} If format cannot be detected or parsing fails
29
+ */
30
+ export declare function parseCookies(content: string | Buffer): ParseResult;
31
+ /**
32
+ * Filter cookies by domain
33
+ *
34
+ * Matches cookies where:
35
+ * - Domain exactly equals the filter
36
+ * - Domain ends with the filter (for subdomain matching)
37
+ * - Filter starts with '.' and domain ends with filter (e.g., '.youtube.com')
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { parseCookies, filterByDomain } from '@mks2508/binary-cookies-parser';
42
+ *
43
+ * const { cookies } = parseCookies(cookieData);
44
+ * const ytCookies = filterByDomain(cookies, '.youtube.com');
45
+ * ```
46
+ *
47
+ * @param cookies - Array of cookies to filter
48
+ * @param domain - Domain to filter by (e.g., '.youtube.com', 'google.com')
49
+ * @returns Filtered array of cookies matching the domain
17
50
  */
18
- export declare class BinaryCookiesParser {
19
- private cookiePath;
20
- private currentBufferPosition;
21
- private data;
22
- private numPages;
23
- private bufferSize;
24
- private pages;
25
- private pageSizes;
26
- private cookies;
27
- /**
28
- * Parse a binary cookies file and return an array of cookies
29
- *
30
- * @param cookiePath - Absolute path to the .binarycookies file
31
- * @returns Array of parsed cookies
32
- * @throws {Error} If file doesn't exist or has invalid format
33
- *
34
- * @example
35
- * ```typescript
36
- * const parser = new BinaryCookiesParser();
37
- * const cookies = await parser.parse('/Users/user/Library/Cookies/Cookies.binarycookies');
38
- * ```
39
- */
40
- parse(cookiePath: string): Promise<BinaryCookie[]>;
41
- private reset;
42
- private openFile;
43
- private readSlice;
44
- private readIntBE;
45
- private readIntLE;
46
- private getNumPages;
47
- private getPageSizes;
48
- private getPages;
49
- private getNumCookies;
50
- private getCookieOffsets;
51
- private getCookieData;
52
- private parseCookieData;
53
- }
51
+ export declare function filterByDomain(cookies: UniversalCookie[], domain: string): UniversalCookie[];
54
52
  /**
55
- * Convenience function to parse a binary cookies file
53
+ * Filter out expired cookies
56
54
  *
57
- * @param cookiePath - Absolute path to the .binarycookies file
58
- * @returns Array of parsed cookies
55
+ * @param cookies - Array of cookies to filter
56
+ * @returns Array of non-expired cookies (includes session cookies without expiry)
57
+ */
58
+ export declare function filterExpired(cookies: UniversalCookie[]): UniversalCookie[];
59
+ /**
60
+ * Convert cookies to Netscape format string
59
61
  *
60
62
  * @example
61
63
  * ```typescript
62
- * import { parseBinaryCookies } from 'binary-cookies-parser';
64
+ * import { parseCookies, toNetscapeFormat } from '@mks2508/binary-cookies-parser';
63
65
  *
64
- * const cookies = await parseBinaryCookies('/path/to/Cookies.binarycookies');
65
- * console.log(cookies);
66
+ * const { cookies } = parseCookies(jsonCookies);
67
+ * const netscapeString = toNetscapeFormat(cookies);
66
68
  * ```
69
+ *
70
+ * @param cookies - Array of cookies to convert
71
+ * @returns Netscape format string (cookies.txt compatible)
72
+ */
73
+ export declare function toNetscapeFormat(cookies: UniversalCookie[]): string;
74
+ /**
75
+ * Convert cookies to JSON format string
76
+ *
77
+ * @param cookies - Array of cookies to convert
78
+ * @returns JSON string representation of cookies
79
+ */
80
+ export declare function toJSONFormat(cookies: UniversalCookie[]): string;
81
+ /**
82
+ * Convert cookies to Cookie header string
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const header = toCookieHeader(cookies);
87
+ * fetch(url, { headers: { Cookie: header } });
88
+ * ```
89
+ *
90
+ * @param cookies - Array of cookies to convert
91
+ * @returns String suitable for Cookie HTTP header (name=value; name2=value2)
67
92
  */
68
- export declare function parseBinaryCookies(cookiePath: string): Promise<BinaryCookie[]>;
93
+ export declare function toCookieHeader(cookies: UniversalCookie[]): string;
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
- import z from"node:fs/promises";import{existsSync as A}from"node:fs";class W{cookiePath=null;currentBufferPosition=0;data=null;numPages=0;bufferSize=0;pages=[];pageSizes=[];cookies=[];async parse(E){if(this.reset(),this.cookiePath=E,!A(E))throw Error(`Cookie file not found: ${E}`);await this.openFile(),this.getNumPages(),this.getPageSizes(),this.getPages();for(let q=0;q<this.pages.length;q++){this.getNumCookies(q),this.getCookieOffsets(q),this.getCookieData(q);for(let F=0;F<this.pages[q].cookies.length;F++){let L=this.parseCookieData(q,F);this.cookies.push(L)}}return this.cookies}reset(){this.cookiePath=null,this.currentBufferPosition=0,this.data=null,this.numPages=0,this.bufferSize=0,this.pages=[],this.pageSizes=[],this.cookies=[]}async openFile(){if(!this.cookiePath)throw Error("Cookie path not set");let E=await z.readFile(this.cookiePath);if(this.data=E,this.bufferSize=E.length,this.readSlice(4).toString()!=="cook")throw Error('Invalid binary cookies file format (missing "cook" header)')}readSlice(E){if(!this.data)throw Error("No data loaded");let q=this.data.subarray(this.currentBufferPosition,this.currentBufferPosition+E);return this.currentBufferPosition+=E,q}readIntBE(){if(!this.data)throw Error("No data loaded");let E=this.data.readInt32BE(this.currentBufferPosition);return this.currentBufferPosition+=4,E}readIntLE(){if(!this.data)throw Error("No data loaded");let E=this.data.readInt32LE(this.currentBufferPosition);return this.currentBufferPosition+=4,E}getNumPages(){return this.numPages=this.readIntBE(),this.numPages}getPageSizes(){for(let E=0;E<this.numPages;E++)this.pageSizes.push(this.readIntBE());return this.pageSizes}getPages(){for(let E of this.pageSizes)this.pages.push({buffer:this.readSlice(E),bufferPosition:0,numCookies:0,cookieOffsets:[],cookies:[]});return this.pages}getNumCookies(E){let q=this.pages[E];q.bufferPosition=0;let F=q.buffer.readInt32BE(q.bufferPosition);if(q.bufferPosition+=4,F!==256)throw Error(`Invalid page header: expected 256, got ${F}`);return q.numCookies=q.buffer.readInt32LE(q.bufferPosition),q.bufferPosition+=4,q.numCookies}getCookieOffsets(E){let q=this.pages[E];q.cookieOffsets=[];for(let F=0;F<q.numCookies;F++)q.cookieOffsets.push(q.buffer.readInt32LE(q.bufferPosition)),q.bufferPosition+=4;return q.cookieOffsets}getCookieData(E){let q=this.pages[E];q.cookies=[];for(let F of q.cookieOffsets){let L=q.buffer.readInt32LE(F);try{q.cookies.push({buffer:q.buffer.subarray(F,F+L)})}catch{q.cookies.push({buffer:q.buffer.subarray(F)})}}return q.cookies}parseCookieData(E,q){let J=this.pages[E].cookies[q].buffer,H=978307200,G=0,T=J.readInt32LE(G);G+=4;let X=J.readInt32LE(G);G+=8;let j=J.readUInt32LE(G),R={},Y=["url","name","path","value"];for(let M of Y)G+=4,R[M]=J.readInt32LE(G);G+=4;let v=J.readUInt32LE(G);G+=8;let Z=J.readDoubleLE(G)+978307200,_=new Date(Z*1000);G+=8;let $=J.readDoubleLE(G)+978307200,w=new Date($*1000),U={flags:X,expiration:_,creation:w};for(let[M,K]of Object.entries(R)){let V="",N=K,Q="";do Q=J.toString("utf8",N,N+1),V+=Q,N++;while(Q!=="\x00");U[M]=V.replace(/\u0000/g,"").trim()}return U}}async function S(E){return new W().parse(E)}export{S as parseBinaryCookies,W as BinaryCookiesParser};
1
+ import{parseNetscape as M,isNetscapeFormat as X}from"./parsers/netscape";import{parseJSON as Q,isJSONFormat as Z}from"./parsers/json";import{BinaryCookiesParser as $,parseBinaryCookies as j,parseBinaryToUniversal as R,binaryToUniversal as w,isBinaryFormat as A}from"./parsers/binary";import{detectFormat as V,tryDetectFormat as x}from"./detector";function H(G){let q=V(G);switch(q){case"netscape":return{format:q,cookies:M(G)};case"json":return{format:q,cookies:Q(Buffer.isBuffer(G)?G.toString("utf8"):G)};case"binary":return{format:q,cookies:R(Buffer.isBuffer(G)?G:Buffer.from(G))}}}function P(G,q){let E=q.toLowerCase();return G.filter((K)=>{let I=K.domain.toLowerCase();if(I===E)return!0;if(E.startsWith("."))return I===E||I.endsWith(E);return I===E||I===`.${E}`||I.endsWith(`.${E}`)})}function J(G){let q=new Date;return G.filter((E)=>{if(!E.expires)return!0;return E.expires>q})}function O(G){let q=["# Netscape HTTP Cookie File"];for(let E of G){let K=E.domain.startsWith(".")?"TRUE":"FALSE",I=E.secure?"TRUE":"FALSE",L=E.expires?Math.floor(E.expires.getTime()/1000):0;q.push([E.domain,K,E.path,I,L,E.name,E.value].join("\t"))}return q.join(`
2
+ `)}function U(G){return JSON.stringify(G.map((q)=>({name:q.name,value:q.value,domain:q.domain,path:q.path,secure:q.secure,httpOnly:q.httpOnly,...q.expires&&{expirationDate:Math.floor(q.expires.getTime()/1000)},...q.sameSite&&{sameSite:q.sameSite.toLowerCase()}})),null,2)}function b(G){return G.map((q)=>`${q.name}=${q.value}`).join("; ")}export{x as tryDetectFormat,O as toNetscapeFormat,U as toJSONFormat,b as toCookieHeader,M as parseNetscape,Q as parseJSON,H as parseCookies,R as parseBinaryToUniversal,j as parseBinaryCookies,X as isNetscapeFormat,Z as isJSONFormat,A as isBinaryFormat,J as filterExpired,P as filterByDomain,V as detectFormat,w as binaryToUniversal,$ as BinaryCookiesParser};
@@ -0,0 +1,96 @@
1
+ import type { BinaryCookie, UniversalCookie } from '../types';
2
+ /**
3
+ * Parser for macOS binary cookies files (.binarycookies)
4
+ *
5
+ * These files are used by Safari and other macOS applications to store cookies
6
+ * in a binary format that's more efficient than plain text.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { BinaryCookiesParser } from '@mks2508/binary-cookies-parser';
11
+ *
12
+ * const parser = new BinaryCookiesParser();
13
+ * const cookies = await parser.parse('/path/to/Cookies.binarycookies');
14
+ * console.log(cookies);
15
+ * ```
16
+ */
17
+ export declare class BinaryCookiesParser {
18
+ private cookiePath;
19
+ private currentBufferPosition;
20
+ private data;
21
+ private numPages;
22
+ private bufferSize;
23
+ private pages;
24
+ private pageSizes;
25
+ private cookies;
26
+ /**
27
+ * Parse a binary cookies file and return an array of cookies
28
+ *
29
+ * @param cookiePath - Absolute path to the .binarycookies file
30
+ * @returns Array of parsed cookies
31
+ * @throws {Error} If file doesn't exist or has invalid format
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const parser = new BinaryCookiesParser();
36
+ * const cookies = await parser.parse('/Users/user/Library/Cookies/Cookies.binarycookies');
37
+ * ```
38
+ */
39
+ parse(cookiePath: string): Promise<BinaryCookie[]>;
40
+ /**
41
+ * Parse a binary cookies buffer directly
42
+ *
43
+ * @param buffer - Buffer containing .binarycookies data
44
+ * @returns Array of parsed cookies
45
+ * @throws {Error} If buffer has invalid format
46
+ */
47
+ parseBuffer(buffer: Buffer): BinaryCookie[];
48
+ private reset;
49
+ private openFile;
50
+ private readSlice;
51
+ private readIntBE;
52
+ private readIntLE;
53
+ private getNumPages;
54
+ private getPageSizes;
55
+ private getPages;
56
+ private getNumCookies;
57
+ private getCookieOffsets;
58
+ private getCookieData;
59
+ private parseCookieData;
60
+ }
61
+ /**
62
+ * Convert BinaryCookie to UniversalCookie format
63
+ *
64
+ * @param cookie - Binary cookie to convert
65
+ * @returns Universal cookie format
66
+ */
67
+ export declare function binaryToUniversal(cookie: BinaryCookie): UniversalCookie;
68
+ /**
69
+ * Parse binary cookies and return UniversalCookie array
70
+ *
71
+ * @param buffer - Buffer containing .binarycookies data
72
+ * @returns Array of universal cookies
73
+ */
74
+ export declare function parseBinaryToUniversal(buffer: Buffer): UniversalCookie[];
75
+ /**
76
+ * Check if buffer appears to be binary cookies format
77
+ *
78
+ * @param buffer - Buffer to check
79
+ * @returns true if buffer starts with 'cook' magic bytes
80
+ */
81
+ export declare function isBinaryFormat(buffer: Buffer): boolean;
82
+ /**
83
+ * Convenience function to parse a binary cookies file
84
+ *
85
+ * @param cookiePath - Absolute path to the .binarycookies file
86
+ * @returns Array of parsed cookies
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * import { parseBinaryCookies } from '@mks2508/binary-cookies-parser';
91
+ *
92
+ * const cookies = await parseBinaryCookies('/path/to/Cookies.binarycookies');
93
+ * console.log(cookies);
94
+ * ```
95
+ */
96
+ export declare function parseBinaryCookies(cookiePath: string): Promise<BinaryCookie[]>;
@@ -0,0 +1,32 @@
1
+ import type { UniversalCookie } from '../types';
2
+ /**
3
+ * Parse cookies from JSON format
4
+ *
5
+ * Supports multiple JSON structures:
6
+ * - Direct array of cookies: [{ name, value, domain, ... }]
7
+ * - Object with cookies property: { cookies: [...] }
8
+ * - Chrome extension export format
9
+ * - Firefox export format
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { parseJSON } from '@mks2508/binary-cookies-parser';
14
+ *
15
+ * const content = JSON.stringify([
16
+ * { name: 'SID', value: 'abc', domain: '.youtube.com', path: '/', secure: true }
17
+ * ]);
18
+ * const cookies = parseJSON(content);
19
+ * ```
20
+ *
21
+ * @param content - JSON string containing cookies
22
+ * @returns Array of parsed cookies
23
+ * @throws {SyntaxError} If content is not valid JSON
24
+ */
25
+ export declare function parseJSON(content: string): UniversalCookie[];
26
+ /**
27
+ * Check if content appears to be JSON format
28
+ *
29
+ * @param content - String content to check
30
+ * @returns true if content starts with { or [
31
+ */
32
+ export declare function isJSONFormat(content: string): boolean;
@@ -0,0 +1,36 @@
1
+ import type { UniversalCookie } from '../types';
2
+ /**
3
+ * Parse cookies from Netscape/Mozilla cookies.txt format
4
+ *
5
+ * Format specification:
6
+ * domain\tflag\tpath\tsecure\texpiration\tname\tvalue
7
+ *
8
+ * - domain: The domain that created and can read the cookie
9
+ * - flag: TRUE if subdomains can access, FALSE otherwise (column 2)
10
+ * - path: The path within the domain for which the cookie is valid
11
+ * - secure: TRUE if HTTPS only, FALSE otherwise
12
+ * - expiration: Unix timestamp (seconds since epoch), 0 for session cookies
13
+ * - name: The cookie name
14
+ * - value: The cookie value
15
+ *
16
+ * Lines starting with # are comments
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * import { parseNetscape } from '@mks2508/binary-cookies-parser';
21
+ *
22
+ * const content = `.youtube.com\tTRUE\t/\tTRUE\t1735689600\tSID\tabcdef123`;
23
+ * const cookies = parseNetscape(content);
24
+ * ```
25
+ *
26
+ * @param content - Content of the cookies.txt file
27
+ * @returns Array of parsed cookies
28
+ */
29
+ export declare function parseNetscape(content: string): UniversalCookie[];
30
+ /**
31
+ * Check if content appears to be in Netscape format
32
+ *
33
+ * @param content - String content to check
34
+ * @returns true if content looks like Netscape format
35
+ */
36
+ export declare function isNetscapeFormat(content: string): boolean;
package/dist/types.d.ts CHANGED
@@ -1,3 +1,40 @@
1
+ /**
2
+ * Universal cookie interface that works across all cookie formats
3
+ * (Netscape, JSON, Binary Safari)
4
+ */
5
+ export interface UniversalCookie {
6
+ /** Cookie name */
7
+ name: string;
8
+ /** Cookie value */
9
+ value: string;
10
+ /** Domain the cookie belongs to (e.g., ".youtube.com") */
11
+ domain: string;
12
+ /** Cookie path (e.g., "/") */
13
+ path: string;
14
+ /** Whether the cookie is secure (HTTPS only) */
15
+ secure: boolean;
16
+ /** Whether the cookie is HTTP-only (not accessible via JavaScript) */
17
+ httpOnly: boolean;
18
+ /** Cookie expiration date */
19
+ expires?: Date;
20
+ /** Cookie creation date */
21
+ creation?: Date;
22
+ /** SameSite attribute for cross-site requests */
23
+ sameSite?: 'Strict' | 'Lax' | 'None';
24
+ }
25
+ /**
26
+ * Supported cookie file formats
27
+ */
28
+ export type CookieFormat = 'netscape' | 'json' | 'binary';
29
+ /**
30
+ * Result from parsing a cookie file
31
+ */
32
+ export interface ParseResult {
33
+ /** Detected format of the input */
34
+ format: CookieFormat;
35
+ /** Array of parsed cookies */
36
+ cookies: UniversalCookie[];
37
+ }
1
38
  /**
2
39
  * Represents a parsed binary cookie from macOS .binarycookies file
3
40
  */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mks2508/binary-cookies-parser",
3
- "version": "1.0.0",
4
- "description": "Modern TypeScript parser for macOS binary cookies files (.binarycookies). Parse Safari and app cookies with zero dependencies.",
3
+ "version": "2.0.0",
4
+ "description": "Universal cookie parser supporting Netscape (cookies.txt), JSON, and macOS binary (.binarycookies) formats with auto-detection.",
5
5
  "author": "MKS2508",
6
6
  "license": "MIT",
7
7
  "type": "module",
@@ -22,17 +22,22 @@
22
22
  ],
23
23
  "keywords": [
24
24
  "cookies",
25
+ "cookie-parser",
26
+ "netscape",
27
+ "cookies-txt",
25
28
  "binarycookies",
26
29
  "safari",
27
30
  "macos",
31
+ "json-cookies",
28
32
  "parser",
29
33
  "typescript",
30
34
  "playwright",
31
35
  "puppeteer",
32
36
  "automation",
33
37
  "binary",
34
- "cookie-parser",
35
- "apple"
38
+ "apple",
39
+ "youtube",
40
+ "yt-dlp"
36
41
  ],
37
42
  "repository": {
38
43
  "type": "git",