cookie-es 0.5.0 → 1.0.0
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/dist/index.cjs +56 -29
- package/dist/index.d.ts +31 -17
- package/dist/index.mjs +56 -27
- package/package.json +22 -9
package/dist/index.cjs
CHANGED
|
@@ -1,53 +1,55 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const decode = decodeURIComponent;
|
|
6
|
-
const encode = encodeURIComponent;
|
|
7
|
-
const pairSplitRegExp = /; */;
|
|
8
|
-
const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
|
3
|
+
const fieldContentRegExp = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;
|
|
9
4
|
function parse(str, options) {
|
|
10
5
|
if (typeof str !== "string") {
|
|
11
6
|
throw new TypeError("argument str must be a string");
|
|
12
7
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
continue;
|
|
8
|
+
const obj = {};
|
|
9
|
+
const opt = options || {};
|
|
10
|
+
const dec = opt.decode || decode;
|
|
11
|
+
let index = 0;
|
|
12
|
+
while (index < str.length) {
|
|
13
|
+
const eqIdx = str.indexOf("=", index);
|
|
14
|
+
if (eqIdx === -1) {
|
|
15
|
+
break;
|
|
22
16
|
}
|
|
23
|
-
let
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
let endIdx = str.indexOf(";", index);
|
|
18
|
+
if (endIdx === -1) {
|
|
19
|
+
endIdx = str.length;
|
|
20
|
+
} else if (endIdx < eqIdx) {
|
|
21
|
+
index = str.lastIndexOf(";", eqIdx - 1) + 1;
|
|
22
|
+
continue;
|
|
27
23
|
}
|
|
28
|
-
|
|
24
|
+
const key = str.slice(index, eqIdx).trim();
|
|
25
|
+
if (void 0 === obj[key]) {
|
|
26
|
+
let val = str.slice(eqIdx + 1, endIdx).trim();
|
|
27
|
+
if (val.codePointAt(0) === 34) {
|
|
28
|
+
val = val.slice(1, -1);
|
|
29
|
+
}
|
|
29
30
|
obj[key] = tryDecode(val, dec);
|
|
30
31
|
}
|
|
32
|
+
index = endIdx + 1;
|
|
31
33
|
}
|
|
32
34
|
return obj;
|
|
33
35
|
}
|
|
34
36
|
function serialize(name, value, options) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
const opt = options || {};
|
|
38
|
+
const enc = opt.encode || encode;
|
|
37
39
|
if (typeof enc !== "function") {
|
|
38
40
|
throw new TypeError("option encode is invalid");
|
|
39
41
|
}
|
|
40
42
|
if (!fieldContentRegExp.test(name)) {
|
|
41
43
|
throw new TypeError("argument name is invalid");
|
|
42
44
|
}
|
|
43
|
-
|
|
45
|
+
const encodedValue = enc(value);
|
|
44
46
|
if (encodedValue && !fieldContentRegExp.test(encodedValue)) {
|
|
45
47
|
throw new TypeError("argument val is invalid");
|
|
46
48
|
}
|
|
47
49
|
let str = name + "=" + encodedValue;
|
|
48
|
-
if (opt.maxAge
|
|
49
|
-
|
|
50
|
-
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
50
|
+
if (void 0 !== opt.maxAge && opt.maxAge !== null) {
|
|
51
|
+
const maxAge = opt.maxAge - 0;
|
|
52
|
+
if (Number.isNaN(maxAge) || !Number.isFinite(maxAge)) {
|
|
51
53
|
throw new TypeError("option maxAge is invalid");
|
|
52
54
|
}
|
|
53
55
|
str += "; Max-Age=" + Math.floor(maxAge);
|
|
@@ -65,7 +67,7 @@ function serialize(name, value, options) {
|
|
|
65
67
|
str += "; Path=" + opt.path;
|
|
66
68
|
}
|
|
67
69
|
if (opt.expires) {
|
|
68
|
-
if (
|
|
70
|
+
if (!isDate(opt.expires) || Number.isNaN(opt.expires.valueOf())) {
|
|
69
71
|
throw new TypeError("option expires is invalid");
|
|
70
72
|
}
|
|
71
73
|
str += "; Expires=" + opt.expires.toUTCString();
|
|
@@ -76,8 +78,24 @@ function serialize(name, value, options) {
|
|
|
76
78
|
if (opt.secure) {
|
|
77
79
|
str += "; Secure";
|
|
78
80
|
}
|
|
81
|
+
if (opt.priority) {
|
|
82
|
+
const priority = typeof opt.priority === "string" ? opt.priority.toLowerCase() : opt.priority;
|
|
83
|
+
switch (priority) {
|
|
84
|
+
case "low":
|
|
85
|
+
str += "; Priority=Low";
|
|
86
|
+
break;
|
|
87
|
+
case "medium":
|
|
88
|
+
str += "; Priority=Medium";
|
|
89
|
+
break;
|
|
90
|
+
case "high":
|
|
91
|
+
str += "; Priority=High";
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
throw new TypeError("option priority is invalid");
|
|
95
|
+
}
|
|
96
|
+
}
|
|
79
97
|
if (opt.sameSite) {
|
|
80
|
-
|
|
98
|
+
const sameSite = typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite;
|
|
81
99
|
switch (sameSite) {
|
|
82
100
|
case true:
|
|
83
101
|
str += "; SameSite=Strict";
|
|
@@ -97,13 +115,22 @@ function serialize(name, value, options) {
|
|
|
97
115
|
}
|
|
98
116
|
return str;
|
|
99
117
|
}
|
|
118
|
+
function isDate(val) {
|
|
119
|
+
return Object.prototype.toString.call(val) === "[object Date]" || val instanceof Date;
|
|
120
|
+
}
|
|
100
121
|
function tryDecode(str, decode2) {
|
|
101
122
|
try {
|
|
102
123
|
return decode2(str);
|
|
103
|
-
} catch
|
|
124
|
+
} catch {
|
|
104
125
|
return str;
|
|
105
126
|
}
|
|
106
127
|
}
|
|
128
|
+
function decode(str) {
|
|
129
|
+
return str.includes("%") ? decodeURIComponent(str) : str;
|
|
130
|
+
}
|
|
131
|
+
function encode(val) {
|
|
132
|
+
return encodeURIComponent(val);
|
|
133
|
+
}
|
|
107
134
|
|
|
108
135
|
exports.parse = parse;
|
|
109
136
|
exports.serialize = serialize;
|
package/dist/index.d.ts
CHANGED
|
@@ -58,6 +58,20 @@ interface CookieSerializeOptions {
|
|
|
58
58
|
* By default, the path is considered the "default path".
|
|
59
59
|
*/
|
|
60
60
|
path?: string | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Specifies the `string` to be the value for the [`Priority` `Set-Cookie` attribute][rfc-west-cookie-priority-00-4.1].
|
|
63
|
+
*
|
|
64
|
+
* - `'low'` will set the `Priority` attribute to `Low`.
|
|
65
|
+
* - `'medium'` will set the `Priority` attribute to `Medium`, the default priority when not set.
|
|
66
|
+
* - `'high'` will set the `Priority` attribute to `High`.
|
|
67
|
+
*
|
|
68
|
+
* More information about the different priority levels can be found in
|
|
69
|
+
* [the specification][rfc-west-cookie-priority-00-4.1].
|
|
70
|
+
*
|
|
71
|
+
* **note** This is an attribute that has not yet been fully standardized, and may change in the future.
|
|
72
|
+
* This also means many clients may ignore this attribute until they understand it.
|
|
73
|
+
*/
|
|
74
|
+
priority?: "low" | "medium" | "high" | undefined;
|
|
61
75
|
/**
|
|
62
76
|
* Specifies the boolean or string to be the value for the {@link https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|`SameSite` `Set-Cookie` attribute}.
|
|
63
77
|
*
|
|
@@ -75,7 +89,7 @@ interface CookieSerializeOptions {
|
|
|
75
89
|
*
|
|
76
90
|
* *note* This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it.
|
|
77
91
|
*/
|
|
78
|
-
sameSite?: true | false |
|
|
92
|
+
sameSite?: true | false | "lax" | "strict" | "none" | undefined;
|
|
79
93
|
/**
|
|
80
94
|
* Specifies the boolean value for the {@link https://tools.ietf.org/html/rfc6265#section-5.2.5|`Secure` `Set-Cookie` attribute}. When truthy, the
|
|
81
95
|
* `Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
|
|
@@ -87,8 +101,8 @@ interface CookieSerializeOptions {
|
|
|
87
101
|
secure?: boolean | undefined;
|
|
88
102
|
}
|
|
89
103
|
/**
|
|
90
|
-
* Additional parsing options
|
|
91
|
-
*/
|
|
104
|
+
* Additional parsing options
|
|
105
|
+
*/
|
|
92
106
|
interface CookieParseOptions {
|
|
93
107
|
/**
|
|
94
108
|
* Specifies a function that will be used to decode a cookie's value. Since
|
|
@@ -106,21 +120,21 @@ interface CookieParseOptions {
|
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
/**
|
|
109
|
-
* Parse an HTTP Cookie header string and returning an object of all cookie
|
|
110
|
-
* name-value pairs.
|
|
111
|
-
*
|
|
112
|
-
* @param str the string representing a `Cookie` header value
|
|
113
|
-
* @param [options] object containing parsing options
|
|
114
|
-
*/
|
|
115
|
-
declare function parse(str: string, options?: CookieParseOptions):
|
|
123
|
+
* Parse an HTTP Cookie header string and returning an object of all cookie
|
|
124
|
+
* name-value pairs.
|
|
125
|
+
*
|
|
126
|
+
* @param str the string representing a `Cookie` header value
|
|
127
|
+
* @param [options] object containing parsing options
|
|
128
|
+
*/
|
|
129
|
+
declare function parse(str: string, options?: CookieParseOptions): Record<string, string>;
|
|
116
130
|
/**
|
|
117
|
-
* Serialize a cookie name-value pair into a `Set-Cookie` header string.
|
|
118
|
-
*
|
|
119
|
-
* @param name the name for the cookie
|
|
120
|
-
* @param value value to set the cookie to
|
|
121
|
-
* @param [options] object containing serialization options
|
|
122
|
-
* @throws {TypeError} when `maxAge` options is invalid
|
|
123
|
-
*/
|
|
131
|
+
* Serialize a cookie name-value pair into a `Set-Cookie` header string.
|
|
132
|
+
*
|
|
133
|
+
* @param name the name for the cookie
|
|
134
|
+
* @param value value to set the cookie to
|
|
135
|
+
* @param [options] object containing serialization options
|
|
136
|
+
* @throws {TypeError} when `maxAge` options is invalid
|
|
137
|
+
*/
|
|
124
138
|
declare function serialize(name: string, value: string, options?: CookieSerializeOptions): string;
|
|
125
139
|
|
|
126
140
|
export { CookieParseOptions, CookieSerializeOptions, parse, serialize };
|
package/dist/index.mjs
CHANGED
|
@@ -1,49 +1,53 @@
|
|
|
1
|
-
const
|
|
2
|
-
const encode = encodeURIComponent;
|
|
3
|
-
const pairSplitRegExp = /; */;
|
|
4
|
-
const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
|
|
1
|
+
const fieldContentRegExp = /^[\u0009\u0020-\u007E\u0080-\u00FF]+$/;
|
|
5
2
|
function parse(str, options) {
|
|
6
3
|
if (typeof str !== "string") {
|
|
7
4
|
throw new TypeError("argument str must be a string");
|
|
8
5
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
continue;
|
|
6
|
+
const obj = {};
|
|
7
|
+
const opt = options || {};
|
|
8
|
+
const dec = opt.decode || decode;
|
|
9
|
+
let index = 0;
|
|
10
|
+
while (index < str.length) {
|
|
11
|
+
const eqIdx = str.indexOf("=", index);
|
|
12
|
+
if (eqIdx === -1) {
|
|
13
|
+
break;
|
|
18
14
|
}
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
let endIdx = str.indexOf(";", index);
|
|
16
|
+
if (endIdx === -1) {
|
|
17
|
+
endIdx = str.length;
|
|
18
|
+
} else if (endIdx < eqIdx) {
|
|
19
|
+
index = str.lastIndexOf(";", eqIdx - 1) + 1;
|
|
20
|
+
continue;
|
|
23
21
|
}
|
|
24
|
-
|
|
22
|
+
const key = str.slice(index, eqIdx).trim();
|
|
23
|
+
if (void 0 === obj[key]) {
|
|
24
|
+
let val = str.slice(eqIdx + 1, endIdx).trim();
|
|
25
|
+
if (val.codePointAt(0) === 34) {
|
|
26
|
+
val = val.slice(1, -1);
|
|
27
|
+
}
|
|
25
28
|
obj[key] = tryDecode(val, dec);
|
|
26
29
|
}
|
|
30
|
+
index = endIdx + 1;
|
|
27
31
|
}
|
|
28
32
|
return obj;
|
|
29
33
|
}
|
|
30
34
|
function serialize(name, value, options) {
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
const opt = options || {};
|
|
36
|
+
const enc = opt.encode || encode;
|
|
33
37
|
if (typeof enc !== "function") {
|
|
34
38
|
throw new TypeError("option encode is invalid");
|
|
35
39
|
}
|
|
36
40
|
if (!fieldContentRegExp.test(name)) {
|
|
37
41
|
throw new TypeError("argument name is invalid");
|
|
38
42
|
}
|
|
39
|
-
|
|
43
|
+
const encodedValue = enc(value);
|
|
40
44
|
if (encodedValue && !fieldContentRegExp.test(encodedValue)) {
|
|
41
45
|
throw new TypeError("argument val is invalid");
|
|
42
46
|
}
|
|
43
47
|
let str = name + "=" + encodedValue;
|
|
44
|
-
if (opt.maxAge
|
|
45
|
-
|
|
46
|
-
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
48
|
+
if (void 0 !== opt.maxAge && opt.maxAge !== null) {
|
|
49
|
+
const maxAge = opt.maxAge - 0;
|
|
50
|
+
if (Number.isNaN(maxAge) || !Number.isFinite(maxAge)) {
|
|
47
51
|
throw new TypeError("option maxAge is invalid");
|
|
48
52
|
}
|
|
49
53
|
str += "; Max-Age=" + Math.floor(maxAge);
|
|
@@ -61,7 +65,7 @@ function serialize(name, value, options) {
|
|
|
61
65
|
str += "; Path=" + opt.path;
|
|
62
66
|
}
|
|
63
67
|
if (opt.expires) {
|
|
64
|
-
if (
|
|
68
|
+
if (!isDate(opt.expires) || Number.isNaN(opt.expires.valueOf())) {
|
|
65
69
|
throw new TypeError("option expires is invalid");
|
|
66
70
|
}
|
|
67
71
|
str += "; Expires=" + opt.expires.toUTCString();
|
|
@@ -72,8 +76,24 @@ function serialize(name, value, options) {
|
|
|
72
76
|
if (opt.secure) {
|
|
73
77
|
str += "; Secure";
|
|
74
78
|
}
|
|
79
|
+
if (opt.priority) {
|
|
80
|
+
const priority = typeof opt.priority === "string" ? opt.priority.toLowerCase() : opt.priority;
|
|
81
|
+
switch (priority) {
|
|
82
|
+
case "low":
|
|
83
|
+
str += "; Priority=Low";
|
|
84
|
+
break;
|
|
85
|
+
case "medium":
|
|
86
|
+
str += "; Priority=Medium";
|
|
87
|
+
break;
|
|
88
|
+
case "high":
|
|
89
|
+
str += "; Priority=High";
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
throw new TypeError("option priority is invalid");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
75
95
|
if (opt.sameSite) {
|
|
76
|
-
|
|
96
|
+
const sameSite = typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite;
|
|
77
97
|
switch (sameSite) {
|
|
78
98
|
case true:
|
|
79
99
|
str += "; SameSite=Strict";
|
|
@@ -93,12 +113,21 @@ function serialize(name, value, options) {
|
|
|
93
113
|
}
|
|
94
114
|
return str;
|
|
95
115
|
}
|
|
116
|
+
function isDate(val) {
|
|
117
|
+
return Object.prototype.toString.call(val) === "[object Date]" || val instanceof Date;
|
|
118
|
+
}
|
|
96
119
|
function tryDecode(str, decode2) {
|
|
97
120
|
try {
|
|
98
121
|
return decode2(str);
|
|
99
|
-
} catch
|
|
122
|
+
} catch {
|
|
100
123
|
return str;
|
|
101
124
|
}
|
|
102
125
|
}
|
|
126
|
+
function decode(str) {
|
|
127
|
+
return str.includes("%") ? decodeURIComponent(str) : str;
|
|
128
|
+
}
|
|
129
|
+
function encode(val) {
|
|
130
|
+
return encodeURIComponent(val);
|
|
131
|
+
}
|
|
103
132
|
|
|
104
133
|
export { parse, serialize };
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cookie-es",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"repository": "unjs/cookie-es",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"type": "module",
|
|
8
8
|
"exports": {
|
|
9
|
-
"
|
|
10
|
-
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.cjs",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
11
14
|
},
|
|
12
15
|
"main": "./dist/index.cjs",
|
|
13
16
|
"module": "./dist/index.mjs",
|
|
@@ -17,11 +20,21 @@
|
|
|
17
20
|
],
|
|
18
21
|
"scripts": {
|
|
19
22
|
"build": "unbuild",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
23
|
+
"dev": "vitest",
|
|
24
|
+
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test",
|
|
25
|
+
"lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test -w",
|
|
26
|
+
"release": "pnpm test && pnpm build && changelogen --release --push && npm publish",
|
|
27
|
+
"test": "pnpm lint && vitest run --coverage"
|
|
22
28
|
},
|
|
23
29
|
"devDependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
"@vitest/coverage-c8": "^0.31.0",
|
|
31
|
+
"changelogen": "^0.5.3",
|
|
32
|
+
"eslint": "^8.39.0",
|
|
33
|
+
"eslint-config-unjs": "^0.1.0",
|
|
34
|
+
"prettier": "^2.8.8",
|
|
35
|
+
"typescript": "^5.0.4",
|
|
36
|
+
"unbuild": "^1.2.1",
|
|
37
|
+
"vitest": "^0.31.0"
|
|
38
|
+
},
|
|
39
|
+
"packageManager": "pnpm@8.4.0"
|
|
40
|
+
}
|