forked from kahnvex/cookie-monster
-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
158 lines (138 loc) · 3.61 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
'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
};
};