UNPKG

@nodecfdi/tough-cookie-file-store

Version:

A JSON file store implementation for tough-cookie module

209 lines (208 loc) 6.43 kB
// src/file_cookie_store.ts import { existsSync, readFileSync, writeFileSync } from "node:fs"; import { inspect } from "node:util"; import { Cookie, pathMatch, permuteDomain, Store } from "tough-cookie"; import { createPromiseCallback } from "tough-cookie/dist/utils.js"; var FileCookieStore = class extends Store { synchronous; /** * @internal */ idx; filePath; constructor(filePath) { super(); this.synchronous = true; this.idx = /* @__PURE__ */ Object.create(null); this.filePath = filePath; this._loadFromFile(); } /** * @internal No doc because this is an overload that supports the implementation */ findCookie(domain, path, key, callback) { const promiseCallback = createPromiseCallback(callback); if (!domain || !path || !key) { return promiseCallback.resolve(void 0); } const result = this.idx[domain]?.[path]?.[key]; return promiseCallback.resolve(result); } /** * @internal No doc because this is an overload that supports the implementation */ findCookies(domain, path, allowSpecialUseDomain = false, callback) { if (typeof allowSpecialUseDomain === "function") { callback = allowSpecialUseDomain; allowSpecialUseDomain = true; } const results = []; const promiseCallback = createPromiseCallback(callback); if (!domain) { return promiseCallback.resolve([]); } let pathMatcher; if (path) { pathMatcher = function matchRFC(domainIndex) { for (const cookiePath in domainIndex) { if (pathMatch(path, cookiePath)) { const pathIndex = domainIndex[cookiePath]; for (const key in pathIndex) { const value = pathIndex[key]; if (value) { results.push(value); } } } } }; } else { pathMatcher = function matchAll(domainIndex) { for (const curPath in domainIndex) { const pathIndex = domainIndex[curPath]; for (const key in pathIndex) { const value = pathIndex[key]; if (value) { results.push(value); } } } }; } const domains = permuteDomain(domain, allowSpecialUseDomain) ?? [domain]; const { idx } = this; for (const curDomain of domains) { const domainIndex = idx[curDomain]; if (!domainIndex) { continue; } pathMatcher(domainIndex); } return promiseCallback.resolve(results); } /** * @internal No doc because this is an overload that supports the implementation */ putCookie(cookie, callback) { const promiseCallback = createPromiseCallback(callback); const { domain, path, key } = cookie; if (!domain || !path || !key) { return promiseCallback.resolve(void 0); } const domainEntry = this.idx[domain] ?? /* @__PURE__ */ Object.create(null); this.idx[domain] = domainEntry; const pathEntry = domainEntry[path] ?? /* @__PURE__ */ Object.create(null); domainEntry[path] = pathEntry; pathEntry[key] = cookie; this._saveToFile(); return promiseCallback.resolve(void 0); } /** * @internal No doc because this is an overload that supports the implementation */ updateCookie(_oldCookie, newCookie, callback) { if (callback) { this.putCookie(newCookie, callback); return; } return this.putCookie(newCookie); } /** * @internal No doc because this is an overload that supports the implementation */ removeCookie(domain, path, key, callback) { const promiseCallback = createPromiseCallback(callback); delete this.idx[domain]?.[path]?.[key]; this._saveToFile(); return promiseCallback.resolve(void 0); } /** * @internal No doc because this is an overload that supports the implementation */ removeCookies(domain, path, callback) { const promiseCallback = createPromiseCallback(callback); const domainEntry = this.idx[domain]; if (domainEntry) { if (path) { delete domainEntry[path]; } else { delete this.idx[domain]; } } this._saveToFile(); return promiseCallback.resolve(void 0); } /** * @internal No doc because this is an overload that supports the implementation */ removeAllCookies(callback) { const promiseCallback = createPromiseCallback(callback); this.idx = /* @__PURE__ */ Object.create(null); this._saveToFile(); return promiseCallback.resolve(void 0); } /** * @internal No doc because this is an overload that supports the implementation */ getAllCookies(callback) { const promiseCallback = createPromiseCallback(callback); const cookies = []; const { idx } = this; const domains = Object.keys(idx); for (const domain of domains) { const domainEntry = idx[domain] ?? {}; const paths = Object.keys(domainEntry); for (const path of paths) { const pathEntry = domainEntry[path] ?? {}; const keys = Object.keys(pathEntry); for (const key of keys) { const keyEntry = pathEntry[key]; if (keyEntry) { cookies.push(keyEntry); } } } } cookies.sort((a, b) => { return (a.creationIndex || 0) - (b.creationIndex || 0); }); return promiseCallback.resolve(cookies); } _loadFromFile() { let data = null; let dataJson = null; if (existsSync(this.filePath)) { data = readFileSync(this.filePath, "utf8"); } if (data) { try { dataJson = JSON.parse(data); } catch (error) { throw new AggregateError( [error], `Could not parse cookie file ${this.filePath}. Please ensure it is not corrupted.` ); } } for (const domainName in dataJson) { for (const pathName in dataJson[domainName]) { for (const cookieName in dataJson[domainName][pathName]) { dataJson[domainName][pathName][cookieName] = Cookie.fromJSON( JSON.stringify(dataJson[domainName][pathName][cookieName]) ); } } } this.idx = dataJson ?? /* @__PURE__ */ Object.create(null); } _saveToFile() { writeFileSync(this.filePath, JSON.stringify(this.idx)); } $inspect() { return `{ idx: ${inspect(this.idx, false, 2)} }`; } }; export { FileCookieStore }; /* istanbul ignore if -- @preserve */