@ouroboros/browser 0.5.6 → 0.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cookies.d.ts CHANGED
@@ -7,6 +7,18 @@
7
7
  * @copyright Ouroboros Coding Inc.
8
8
  * @created 2018-11-24
9
9
  */
10
+ export type setOptions = {
11
+ Domain?: string;
12
+ Expires?: number;
13
+ Path?: string;
14
+ Secure?: boolean;
15
+ SameSite?: 'Strict' | 'Lax' | 'None';
16
+ Partitioned?: boolean;
17
+ };
18
+ export type removeOptions = {
19
+ Domain?: string;
20
+ Path?: string;
21
+ };
10
22
  /**
11
23
  * Get
12
24
  *
@@ -15,38 +27,38 @@
15
27
  * @name get
16
28
  * @access public
17
29
  * @param {string} name The name of the cookie to fetch
18
- * @param {string} defaulReturn The default value to return if no cookie is found
30
+ * @param {string} defaultReturn The default value to return if no cookie is found
19
31
  * @return {string | object | null}
20
32
  */
21
- declare function get(name: string, defaulReturn: string | null | undefined): string | object | null;
33
+ declare function get(name?: string, defaultReturn?: string): string | object | null;
22
34
  /**
23
35
  * Remove
24
36
  *
25
- * Deletes a cookie
37
+ * Removes a cookie.
26
38
  *
27
- * @name remove
28
- * @access public
29
- * @param {string} name The name of the cookie to delete
30
- * @param {string?} domain The domain of the cookie
31
- * @param {string?} path The path of the cookie
32
- * @return {void}
39
+ * @deprecated The (domain, path) positional signature is deprecated and will be
40
+ * removed in a future version. Pass an options object instead:
41
+ * remove(name, { Domain, Path })
33
42
  */
34
43
  declare function remove(name: string, domain?: string, path?: string): void;
35
44
  /**
36
- * Set
45
+ * Remove
37
46
  *
38
- * Sets a cookie
47
+ * Removes a cookie using an options object.
48
+ */
49
+ declare function remove(name: string, options?: removeOptions): void;
50
+ /**
51
+ * Sets a cookie.
39
52
  *
40
- * @name set
41
- * @access public
42
- * @param {string} name The name of the cookie
43
- * @param {string} value The value to store
44
- * @param {number} expires The number of seconds before the cookie expires
45
- * @param {string?} domain The optional domain to set the cookie on
46
- * @param {string?} path The optional path of the cookie
47
- * @return {void}
53
+ * @deprecated The (expires, domain, path) positional signature is deprecated
54
+ * and will be removed in a future version. Pass an options object instead:
55
+ * set(name, value, { Expires, Domain, Path })
48
56
  */
49
57
  declare function set(name: string, value: string, expires?: number, domain?: string, path?: string): void;
58
+ /**
59
+ * Sets a cookie using an options object.
60
+ */
61
+ declare function set(name: string, value: string, options?: setOptions): void;
50
62
  declare const cookies: {
51
63
  get: typeof get;
52
64
  remove: typeof remove;
package/cookies.js CHANGED
@@ -15,77 +15,153 @@
15
15
  * @name get
16
16
  * @access public
17
17
  * @param {string} name The name of the cookie to fetch
18
- * @param {string} defaulReturn The default value to return if no cookie is found
18
+ * @param {string} defaultReturn The default value to return if no cookie is found
19
19
  * @return {string | object | null}
20
20
  */
21
- function get(name, defaulReturn) {
21
+ function get(name, defaultReturn) {
22
22
  // Set the default if no value is passed
23
- if (typeof defaulReturn === 'undefined') {
24
- defaulReturn = null;
25
- }
23
+ const defRet = (typeof defaultReturn === 'undefined')
24
+ ? null
25
+ : defaultReturn;
26
26
  // Parse all cookies
27
27
  const oCookies = {};
28
28
  const lCookies = document.cookie.split(';');
29
29
  for (const s of lCookies) {
30
- const l = s.split('=');
31
- oCookies[l[0].trimStart()] = decodeURIComponent(l[1]);
30
+ const i = s.indexOf('=');
31
+ if (i === -1)
32
+ continue;
33
+ oCookies[s.slice(0, i).trimStart()] = decodeURIComponent(s.slice(i + 1));
32
34
  }
33
35
  // If there's no name, return all
34
36
  if (typeof name === 'undefined') {
35
37
  return oCookies;
36
38
  }
37
39
  // If the cookie exists return it, else return the default
38
- return (name in oCookies) ? oCookies[name] : defaulReturn;
40
+ return (name in oCookies) ? oCookies[name] : defRet;
39
41
  }
40
42
  /**
41
43
  * Remove
42
44
  *
43
- * Deletes a cookie
45
+ * Removes a cookie.
44
46
  *
45
47
  * @name remove
46
48
  * @access public
47
- * @param {string} name The name of the cookie to delete
48
- * @param {string?} domain The domain of the cookie
49
- * @param {string?} path The path of the cookie
50
- * @return {void}
49
+ * @param name The name of the cookie to delete
50
+ * @param options The optional settings: Domain, Path
51
51
  */
52
- function remove(name, domain, path) {
53
- set(name, '', -86400, domain, path);
52
+ function remove(name, optionsOrDomain, ...rest) {
53
+ // Init options
54
+ let options = {};
55
+ // Detect new options-object format
56
+ if (optionsOrDomain !== null && typeof optionsOrDomain === 'object') {
57
+ options = { ...optionsOrDomain };
58
+ }
59
+ // Detect legacy (deprecated) format
60
+ else if (typeof optionsOrDomain === 'string' || rest.length > 0) {
61
+ console.warn('remove: passing (domain, path) as separate arguments is ' +
62
+ 'deprecated and will be removed in a future version. Pass an ' +
63
+ 'options object instead: remove(name, { Domain, Path })');
64
+ const [path] = rest;
65
+ options = {
66
+ Domain: optionsOrDomain,
67
+ Path: path
68
+ };
69
+ }
70
+ // No options passed
71
+ else {
72
+ options = {};
73
+ }
74
+ // Add the expires to clear it immediately
75
+ options.Expires = 0;
76
+ // Call set with no value and a time in the past
77
+ set(name, '', options);
54
78
  }
55
79
  /**
56
80
  * Set
57
81
  *
58
- * Sets a cookie
82
+ * Sets a cookie.
59
83
  *
60
- * @name set
61
- * @access public
62
- * @param {string} name The name of the cookie
63
- * @param {string} value The value to store
64
- * @param {number} expires The number of seconds before the cookie expires
65
- * @param {string?} domain The optional domain to set the cookie on
66
- * @param {string?} path The optional path of the cookie
67
- * @return {void}
84
+ * @param name The name of the cookie
85
+ * @param value The value to store
86
+ * @param options The optional settings: Domain, Expires, Path, Secure,
87
+ * SameSite, Partitioned
68
88
  */
69
- function set(name, value, expires, domain, path) {
89
+ function set(name, value, optionsOrExpires, ...rest) {
90
+ // If no name was passed
91
+ if (!name) {
92
+ throw new Error('set: name is required');
93
+ }
94
+ // Init options
95
+ let options;
96
+ // Detect new options-object format
97
+ if (optionsOrExpires !== null && typeof optionsOrExpires === 'object') {
98
+ options = optionsOrExpires;
99
+ }
100
+ // Detect legacy (deprecated) format
101
+ else if (typeof optionsOrExpires === 'number' || rest.length > 0) {
102
+ // Warn the user to update the code
103
+ console.warn('set: passing (expires, domain, path) as separate arguments is ' +
104
+ 'deprecated and will be removed in a future version. Pass an ' +
105
+ 'options object instead: set(name, value, { Expires, Domain, ' +
106
+ 'Path })');
107
+ // Pull out the domain and path if they exist
108
+ const [domain, path] = rest;
109
+ // Create the new format from the old format
110
+ options = {
111
+ Expires: optionsOrExpires,
112
+ Domain: domain,
113
+ Path: path,
114
+ };
115
+ }
116
+ // No options passed
117
+ else {
118
+ options = {};
119
+ }
70
120
  // Init the sections with the name and value
71
121
  const lSections = [
72
122
  `${name}=${encodeURIComponent(value)}`
73
123
  ];
74
124
  // If we have an expires
75
- if (expires) {
125
+ if (options.Expires) {
76
126
  // Generate the expires time
77
127
  const d = new Date();
78
- d.setTime(d.getTime() + (expires * 1000));
128
+ d.setTime(d.getTime() + (options.Expires * 1000));
79
129
  // Add it to the sections
80
- lSections.push(`expires=${d.toUTCString()}`);
130
+ lSections.push(`Expires=${d.toUTCString()}`);
81
131
  }
82
132
  // If we have a domain
83
- if (domain) {
84
- lSections.push(`domain=${domain}`);
133
+ if (options.Domain) {
134
+ lSections.push(`Domain=${options.Domain}`);
85
135
  }
86
136
  // If we have a path
87
- if (path) {
88
- lSections.push(`path=${path}`);
137
+ if (options.Path) {
138
+ lSections.push(`Path=${options.Path}`);
139
+ }
140
+ // If we want secure
141
+ if (options.Secure) {
142
+ lSections.push('Secure');
143
+ }
144
+ // If we want SameSite
145
+ if (options.SameSite) {
146
+ // If the value is 'None' and Secure is not turned on
147
+ if (options.SameSite === 'None' && !options.Secure) {
148
+ // Warn the user this is invalid
149
+ console.warn('set: SameSite as None without Secure is invalid and the ' +
150
+ 'browser will most likely fail to create the cookie.');
151
+ }
152
+ // Set it
153
+ lSections.push(`SameSite=${options.SameSite}`);
154
+ }
155
+ // If we want partitioned
156
+ if (options.Partitioned) {
157
+ // If the value is true and Secure is not turned on
158
+ if (options.Partitioned && !options.Secure) {
159
+ // Warn the user this is invalid
160
+ console.warn('set: Partitioned without Secure is invalid and the ' +
161
+ 'browser will most likely fail to create the cookie.');
162
+ }
163
+ // Set it
164
+ lSections.push('Partitioned');
89
165
  }
90
166
  // Set the cookie by combining the sections
91
167
  document.cookie = lSections.join('; ');
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouroboros/browser",
3
- "version": "0.5.6",
3
+ "version": "0.5.7",
4
4
  "description": "Package to handle common browser functionality.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/src/cookies.ts CHANGED
@@ -8,6 +8,20 @@
8
8
  * @created 2018-11-24
9
9
  */
10
10
 
11
+ // Types
12
+ export type setOptions = {
13
+ Domain?: string,
14
+ Expires?: number,
15
+ Path?: string,
16
+ Secure?: boolean,
17
+ SameSite?: 'Strict' | 'Lax' | 'None',
18
+ Partitioned?: boolean
19
+ }
20
+ export type removeOptions = {
21
+ Domain?: string,
22
+ Path?: string
23
+ }
24
+
11
25
  /**
12
26
  * Get
13
27
  *
@@ -16,22 +30,26 @@
16
30
  * @name get
17
31
  * @access public
18
32
  * @param {string} name The name of the cookie to fetch
19
- * @param {string} defaulReturn The default value to return if no cookie is found
33
+ * @param {string} defaultReturn The default value to return if no cookie is found
20
34
  * @return {string | object | null}
21
35
  */
22
- function get(name: string, defaulReturn: string | null | undefined): string | object | null {
36
+ function get(
37
+ name?: string,
38
+ defaultReturn?: string
39
+ ): string | object | null {
23
40
 
24
41
  // Set the default if no value is passed
25
- if(typeof defaulReturn === 'undefined') {
26
- defaulReturn = null;
27
- }
42
+ const defRet = (typeof defaultReturn === 'undefined')
43
+ ? null
44
+ : defaultReturn;
28
45
 
29
46
  // Parse all cookies
30
- const oCookies: Record<string, string> = {};
47
+ const oCookies: Record<string, string> = { };
31
48
  const lCookies = document.cookie.split(';');
32
49
  for(const s of lCookies) {
33
- const l = s.split('=');
34
- oCookies[l[0].trimStart()] = decodeURIComponent(l[1]);
50
+ const i = s.indexOf('=');
51
+ if (i === -1) continue;
52
+ oCookies[s.slice(0, i).trimStart()] = decodeURIComponent(s.slice(i + 1));
35
53
  }
36
54
 
37
55
  // If there's no name, return all
@@ -40,40 +58,147 @@ function get(name: string, defaulReturn: string | null | undefined): string | ob
40
58
  }
41
59
 
42
60
  // If the cookie exists return it, else return the default
43
- return (name in oCookies) ? oCookies[name] : defaulReturn;
61
+ return (name in oCookies) ? oCookies[name] : defRet;
44
62
  }
45
63
 
46
64
  /**
47
65
  * Remove
48
66
  *
49
- * Deletes a cookie
67
+ * Removes a cookie.
68
+ *
69
+ * @deprecated The (domain, path) positional signature is deprecated and will be
70
+ * removed in a future version. Pass an options object instead:
71
+ * remove(name, { Domain, Path })
72
+ */
73
+ function remove(name: string, domain?: string, path?: string): void;
74
+
75
+ /**
76
+ * Remove
77
+ *
78
+ * Removes a cookie using an options object.
79
+ */
80
+ function remove(name: string, options?: removeOptions): void;
81
+
82
+ /**
83
+ * Remove
84
+ *
85
+ * Removes a cookie.
50
86
  *
51
87
  * @name remove
52
88
  * @access public
53
- * @param {string} name The name of the cookie to delete
54
- * @param {string?} domain The domain of the cookie
55
- * @param {string?} path The path of the cookie
56
- * @return {void}
89
+ * @param name The name of the cookie to delete
90
+ * @param options The optional settings: Domain, Path
57
91
  */
58
- function remove(name: string, domain?: string, path?: string): void {
59
- set(name, '', -86400, domain, path);
92
+ function remove(
93
+ name: string,
94
+ optionsOrDomain?: removeOptions | string,
95
+ ...rest: [ path?: string ]
96
+ ): void {
97
+
98
+ // Init options
99
+ let options: setOptions = { };
100
+
101
+ // Detect new options-object format
102
+ if(optionsOrDomain !== null && typeof optionsOrDomain === 'object') {
103
+ options = { ...optionsOrDomain };
104
+ }
105
+
106
+ // Detect legacy (deprecated) format
107
+ else if(typeof optionsOrDomain === 'string' || rest.length > 0) {
108
+ console.warn(
109
+ 'remove: passing (domain, path) as separate arguments is ' +
110
+ 'deprecated and will be removed in a future version. Pass an ' +
111
+ 'options object instead: remove(name, { Domain, Path })'
112
+ );
113
+ const [ path ] = rest;
114
+ options = {
115
+ Domain: optionsOrDomain,
116
+ Path: path
117
+ }
118
+ }
119
+
120
+ // No options passed
121
+ else {
122
+ options = {};
123
+ }
124
+
125
+ // Add the expires to clear it immediately
126
+ options.Expires = 0;
127
+
128
+ // Call set with no value and a time in the past
129
+ set(name, '', options);
60
130
  }
61
131
 
132
+ /**
133
+ * Sets a cookie.
134
+ *
135
+ * @deprecated The (expires, domain, path) positional signature is deprecated
136
+ * and will be removed in a future version. Pass an options object instead:
137
+ * set(name, value, { Expires, Domain, Path })
138
+ */
139
+ function set(name: string, value: string, expires?: number, domain?: string, path?: string): void;
140
+
141
+ /**
142
+ * Sets a cookie using an options object.
143
+ */
144
+ function set(name: string, value: string, options?: setOptions): void;
145
+
62
146
  /**
63
147
  * Set
64
148
  *
65
- * Sets a cookie
149
+ * Sets a cookie.
66
150
  *
67
- * @name set
68
- * @access public
69
- * @param {string} name The name of the cookie
70
- * @param {string} value The value to store
71
- * @param {number} expires The number of seconds before the cookie expires
72
- * @param {string?} domain The optional domain to set the cookie on
73
- * @param {string?} path The optional path of the cookie
74
- * @return {void}
151
+ * @param name The name of the cookie
152
+ * @param value The value to store
153
+ * @param options The optional settings: Domain, Expires, Path, Secure,
154
+ * SameSite, Partitioned
75
155
  */
76
- function set(name: string, value: string, expires?: number, domain?: string, path?: string): void {
156
+ function set(
157
+ name: string,
158
+ value: string,
159
+ optionsOrExpires?: setOptions | number,
160
+ ...rest: [domain?: string, path?: string]
161
+ ): void {
162
+
163
+ // If no name was passed
164
+ if(!name) {
165
+ throw new Error('set: name is required');
166
+ }
167
+
168
+ // Init options
169
+ let options: setOptions;
170
+
171
+ // Detect new options-object format
172
+ if(optionsOrExpires !== null && typeof optionsOrExpires === 'object') {
173
+ options = optionsOrExpires;
174
+ }
175
+
176
+ // Detect legacy (deprecated) format
177
+ else if(typeof optionsOrExpires === 'number' || rest.length > 0) {
178
+
179
+ // Warn the user to update the code
180
+ console.warn(
181
+ 'set: passing (expires, domain, path) as separate arguments is ' +
182
+ 'deprecated and will be removed in a future version. Pass an ' +
183
+ 'options object instead: set(name, value, { Expires, Domain, ' +
184
+ 'Path })'
185
+ );
186
+
187
+ // Pull out the domain and path if they exist
188
+ const [domain, path] = rest;
189
+
190
+ // Create the new format from the old format
191
+ options = {
192
+ Expires: optionsOrExpires,
193
+ Domain: domain,
194
+ Path: path,
195
+ };
196
+ }
197
+
198
+ // No options passed
199
+ else {
200
+ options = {};
201
+ }
77
202
 
78
203
  // Init the sections with the name and value
79
204
  const lSections = [
@@ -81,24 +206,63 @@ function set(name: string, value: string, expires?: number, domain?: string, pat
81
206
  ];
82
207
 
83
208
  // If we have an expires
84
- if(expires) {
209
+ if(options.Expires) {
85
210
 
86
211
  // Generate the expires time
87
212
  const d = new Date();
88
- d.setTime(d.getTime() + (expires * 1000))
213
+ d.setTime(d.getTime() + (options.Expires * 1000));
89
214
 
90
215
  // Add it to the sections
91
- lSections.push(`expires=${d.toUTCString()}`);
216
+ lSections.push(`Expires=${d.toUTCString()}`);
92
217
  }
93
218
 
94
219
  // If we have a domain
95
- if(domain) {
96
- lSections.push(`domain=${domain}`);
220
+ if(options.Domain) {
221
+ lSections.push(`Domain=${options.Domain}`);
97
222
  }
98
223
 
99
224
  // If we have a path
100
- if(path) {
101
- lSections.push(`path=${path}`);
225
+ if(options.Path) {
226
+ lSections.push(`Path=${options.Path}`);
227
+ }
228
+
229
+ // If we want secure
230
+ if(options.Secure) {
231
+ lSections.push('Secure');
232
+ }
233
+
234
+ // If we want SameSite
235
+ if(options.SameSite) {
236
+
237
+ // If the value is 'None' and Secure is not turned on
238
+ if(options.SameSite === 'None' && !options.Secure) {
239
+
240
+ // Warn the user this is invalid
241
+ console.warn(
242
+ 'set: SameSite as None without Secure is invalid and the ' +
243
+ 'browser will most likely fail to create the cookie.'
244
+ )
245
+ }
246
+
247
+ // Set it
248
+ lSections.push(`SameSite=${options.SameSite}`);
249
+ }
250
+
251
+ // If we want partitioned
252
+ if(options.Partitioned) {
253
+
254
+ // If the value is true and Secure is not turned on
255
+ if(options.Partitioned && !options.Secure) {
256
+
257
+ // Warn the user this is invalid
258
+ console.warn(
259
+ 'set: Partitioned without Secure is invalid and the ' +
260
+ 'browser will most likely fail to create the cookie.'
261
+ );
262
+ }
263
+
264
+ // Set it
265
+ lSections.push('Partitioned');
102
266
  }
103
267
 
104
268
  // Set the cookie by combining the sections
@@ -107,4 +271,4 @@ function set(name: string, value: string, expires?: number, domain?: string, pat
107
271
 
108
272
  // Default export
109
273
  const cookies = { get, remove, set };
110
- export default cookies;
274
+ export default cookies;
Binary file