UNPKG

msw

Version:

Seamless REST/GraphQL API mocking library for browser and Node.js.

95 lines (77 loc) 2.52 kB
import { isNodeProcess } from 'is-node-process' import { invariant } from 'outvariant' import { Cookie, CookieJar, MemoryCookieStore, type MemoryCookieStoreIndex, } from 'tough-cookie' import { jsonParse } from './internal/jsonParse' class CookieStore { #storageKey = '__msw-cookie-store__' #jar: CookieJar #memoryStore: MemoryCookieStore constructor() { if (!isNodeProcess()) { invariant( typeof localStorage !== 'undefined', 'Failed to create a CookieStore: `localStorage` is not available in this environment. This is likely an issue with your environment, which has been detected as browser (or browser-like) environment and must implement global browser APIs correctly.', ) } this.#memoryStore = new MemoryCookieStore() this.#memoryStore.idx = this.getCookieStoreIndex() this.#jar = new CookieJar(this.#memoryStore) } public getCookies(url: string): Array<Cookie> { return this.#jar.getCookiesSync(url) } public async setCookie(cookieName: string, url: string): Promise<void> { await this.#jar.setCookie(cookieName, url) this.persist() } private getCookieStoreIndex(): MemoryCookieStoreIndex { if ( typeof localStorage === 'undefined' || typeof localStorage.getItem !== 'function' ) { return {} } const cookiesString = localStorage.getItem(this.#storageKey) if (cookiesString == null) { return {} } const rawCookies = jsonParse<Array<Record<string, unknown>>>(cookiesString) if (rawCookies == null) { return {} } const cookies: MemoryCookieStoreIndex = {} for (const rawCookie of rawCookies) { const cookie = Cookie.fromJSON(rawCookie) if (cookie != null && cookie.domain != null && cookie.path != null) { cookies[cookie.domain] ||= {} cookies[cookie.domain][cookie.path] ||= {} cookies[cookie.domain][cookie.path][cookie.key] = cookie } } return cookies } private persist(): void { if ( typeof localStorage === 'undefined' || typeof localStorage.setItem !== 'function' ) { return } const data = [] const { idx } = this.#memoryStore for (const domain in idx) { for (const path in idx[domain]) { for (const key in idx[domain][path]) { data.push(idx[domain][path][key].toJSON()) } } } localStorage.setItem(this.#storageKey, JSON.stringify(data)) } } export const cookieStore = new CookieStore()