UNPKG

koekiemonster

Version:

Browser and Nodejs compatible cookie interface

159 lines (138 loc) 3.7 kB
'use strict'; /** * Cookie creation interface. * * @param {Object} doc Reference to the document. * @returns {Object} Session storage inspired API. * @public */ module.exports = function bake(doc, options){ var str = 'string'; // Reduce bytes by caching str. var decode = decodeURIComponent; // Reduce lookups by smaller names. var encode = encodeURIComponent; // Same as above. // // We want to provide a sane out of the box DX, and the most common use // case would be loading cookies from the browser's `document.cookie` // location. So when no document is provided, we should attempt to // default to that without breaking any native environment. // if (!doc) { doc = 'undefined' !== typeof document && str === typeof document.cookie ? document : {}; } if (!options) options = {}; if (typeof doc === str) doc = { cookie: doc }; else if (typeof doc.cookie !== str) doc.cookie = ''; /** * Regular Expression that is used to split cookies into individual items. * * @type {RegExp} * @private */ var splitter = /;\s*/; /** * Date used to removed cookies. * * @type {String} * @private */ var remove = new Date(0).toUTCString(); /** * Read out all the cookies. * * @returns {Array} * @private */ function read() { return options.read ? options.read() : doc.cookie.split(splitter); } /** * Write a new cookie. * * @param {String} cookie Cookie value. * @param {Object} meta Additional cookie information. * @returns {String} * @private */ function write(cookie, meta) { return options.write ? options.write(cookie, meta) : (doc.cookie = cookie); } /** * Get the contents of a cookie. * * @param {String} key Name of the cookie we want to fetch. * @returns {String|Undefined} Result of the cookie or nothing. * @public */ function getItem(key) { var cookies = read(); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i]; var index = cookie.indexOf('='); var name = decode(cookie.slice(0, index)); if (name === key) return decode(cookie.slice(index + 1)); } } /** * Set a new cookie. * * @param {String} key Name of the cookie. * @param {String} value Data for the cookie. * @param {Object} opts Options for the cookie setting. * @returns {String} Cookie. * @public */ function setItem(key, value, opts) { if (typeof key !== str || typeof value !== str) return false; if (!opts) opts = {}; value = encode(value); key = encode(key); var cookie = key + '=' + value; if ('expires' in opts) cookie += '; expires=' + opts.expires; if ('path' in opts) cookie += '; path=' + opts.path; if ('domain' in opts) cookie += '; domain=' + opts.domain; if (opts.secure) cookie += '; secure'; return write(cookie, { remove: opts.expires === remove, value: value, opts: opts, key: key }); } /** * Remove a cookie. * * @param {String} key Name of the cookie. * @param {Object} opts Options for the cookie setting. * @returns {Undefined} Void. * @public */ function removeItem(key, opts) { if (!opts) opts = {}; opts.expires = remove; return setItem(key, '', opts); } /** * Clear all cookies. * * @returns {Undefined} Void. * @public */ function clear() { var cookies = read(); for (var i = 0; i < cookies.length; i++) { removeItem(decode(cookies[i].split('=')[0])); } } return { removeItem: removeItem, getItem: getItem, setItem: setItem, clear: clear }; };