UNPKG

quasar-framework

Version:

Build responsive SPA, SSR, PWA, Hybrid Mobile Apps and Electron apps, all simultaneously using the same codebase

158 lines (130 loc) 3.44 kB
import { isSSR } from './platform.js' function encode (string) { return encodeURIComponent(string) } function decode (string) { return decodeURIComponent(string) } function stringifyCookieValue (value) { return encode(value === Object(value) ? JSON.stringify(value) : '' + value) } function read (string) { if (string === '') { return string } if (string.indexOf('"') === 0) { // This is a quoted cookie as according to RFC2068, unescape... string = string.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\') } // Replace server-side written pluses with spaces. // If we can't decode the cookie, ignore it, it's unusable. // If we can't parse the cookie, ignore it, it's unusable. string = decode(string.replace(/\+/g, ' ')) try { string = JSON.parse(string) } catch (e) {} return string } function set (key, val, opts = {}, ssr) { let time = opts.expires const hasExpire = typeof opts.expires === 'number' if (hasExpire) { time = new Date() time.setMilliseconds(time.getMilliseconds() + opts.expires * 864e+5) } const keyValue = `${encode(key)}=${stringifyCookieValue(val)}` const cookie = [ keyValue, time ? '; Expires=' + time.toUTCString() : '', // use expires attribute, max-age is not supported by IE opts.path ? '; Path=' + opts.path : '', opts.domain ? '; Domain=' + opts.domain : '', opts.httpOnly ? '; HttpOnly' : '', opts.secure ? '; Secure' : '' ].join('') if (ssr) { ssr.res.setHeader('Set-Cookie', cookie) // make temporary update so future get() // within same SSR timeframe would return the set value let all = ssr.req.headers.cookie || '' if (hasExpire && opts.expires < 0) { const val = get(key, ssr) if (val !== undefined) { all = all .replace(`${key}=${val}; `, '') .replace(`; ${key}=${val}`, '') .replace(`${key}=${val}`, '') } } else { all = all ? `${keyValue}; ${all}` : cookie } ssr.req.headers.cookie = all } else { document.cookie = cookie } } function get (key, ssr) { let result = key ? undefined : {}, cookieSource = ssr ? ssr.req.headers : document, cookies = cookieSource.cookie ? cookieSource.cookie.split('; ') : [], i = 0, l = cookies.length, parts, name, cookie for (; i < l; i++) { parts = cookies[i].split('=') name = decode(parts.shift()) cookie = parts.join('=') if (!key) { result[name] = cookie } else if (key === name) { result = read(cookie) break } } return result } function remove (key, options, ssr) { set( key, '', Object.assign({}, options, { expires: -1 }), ssr ) } function has (key, ssr) { return get(key, ssr) !== undefined } export function getObject (ctx = {}) { const ssr = ctx.ssr return { get: key => get(key, ssr), set: (key, val, opts) => set(key, val, opts, ssr), has: key => has(key, ssr), remove: (key, options) => remove(key, options, ssr), all: () => get(null, ssr) } } export default { parseSSR (/* ssrContext */ ssr) { return ssr ? getObject({ ssr }) : this }, install ({ $q, queues }) { if (isSSR) { queues.server.push((q, ctx) => { q.cookies = getObject(ctx) }) } else { Object.assign(this, getObject()) $q.cookies = this } } }