UNPKG

@whatwg-node/cookie-store

Version:
115 lines (114 loc) 3.78 kB
import { fakePromise } from '@whatwg-node/promise-helpers'; import { CookieChangeEvent } from './CookieChangeEvent.js'; import { parse } from './parse.js'; export class CookieStore extends EventTarget { onchange; cookieMap = new Map(); get [Symbol.toStringTag]() { return 'CookieStore'; } constructor(cookieString) { super(); this.cookieMap = parse(cookieString); } get(init) { if (init == null) { throw new TypeError('CookieStoreGetOptions must not be empty'); } else if (init instanceof Object && !Object.keys(init).length) { throw new TypeError('CookieStoreGetOptions must not be empty'); } return this.getAll(init).then(cookies => cookies[0]); } async set(init, possibleValue) { const item = { name: '', value: '', path: '/', secure: false, sameSite: 'strict', expires: null, domain: null, httpOnly: false, }; if (typeof init === 'string') { item.name = init; item.value = possibleValue; } else { Object.assign(item, init); if (item.path && !item.path.startsWith('/')) { throw new TypeError('Cookie path must start with "/"'); } if (item.domain?.startsWith('.')) { throw new TypeError('Cookie domain cannot start with "."'); } if (item.name?.startsWith('__Host') && item.domain) { throw new TypeError('Cookie domain must not be specified for host cookies'); } if (item.name?.startsWith('__Host') && item.path !== '/') { throw new TypeError('Cookie path must not be specified for host cookies'); } if (item.path && item.path.endsWith('/')) { item.path = item.path.slice(0, -1); } if (item.path === '') { item.path = '/'; } } if (item.name === '' && item.value && item.value.includes('=')) { throw new TypeError("Cookie value cannot contain '=' if the name is empty"); } if (item.name && item.name.startsWith('__Host')) { item.secure = true; } const previousCookie = await this.get(item.name); this.cookieMap.set(item.name || '', item); if (this.onchange) { const changed = []; const deleted = []; if (previousCookie && !(await this.get(item))) { deleted.push({ ...item, value: undefined }); } else { changed.push(item); } const event = new CookieChangeEvent('change', { changed, deleted }); this.onchange(event); } } getAll(init) { const cookies = Array.from(this.cookieMap.values()); if (init == null || Object.keys(init).length === 0) { return fakePromise(cookies); } let name; if (typeof init === 'string') { name = init; } else { name = init.name; } return fakePromise(cookies.filter(cookie => cookie.name === name)); } delete(init) { const item = { name: '', value: '', path: '/', secure: false, sameSite: 'strict', expires: null, domain: null, httpOnly: false, }; if (typeof init === 'string') { item.name = init; } else { Object.assign(item, init); } item.expires = 0; return this.set(item); } }