whatwg-mimetype 2.3.0 → 4.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/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright © 2017–2018 Domenic Denicola <d@domenic.me>
1
+ Copyright © Domenic Denicola <d@domenic.me>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
package/README.md CHANGED
@@ -24,7 +24,7 @@ console.assert(mimeType.isXML() === false);
24
24
 
25
25
  Parsing is a fairly complex process; see [the specification](https://mimesniff.spec.whatwg.org/#parsing-a-mime-type) for details (and similarly [for serialization](https://mimesniff.spec.whatwg.org/#serializing-a-mime-type)).
26
26
 
27
- This package's algorithms conform to those of the WHATWG [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/), and is aligned up to commit [126286a](https://github.com/whatwg/mimesniff/commit/126286ab2dcf3e2d541349ed93539a88bf394ad5).
27
+ This package's algorithms conform to those of the WHATWG [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/), and is aligned up to commit [8e9a7dd](https://github.com/whatwg/mimesniff/commit/8e9a7dd90717c595a4e4d982cd216e4411d33736).
28
28
 
29
29
  ## `MIMEType` API
30
30
 
@@ -52,7 +52,7 @@ As an alternative to the constructor, you can use `MIMEType.parse(string)`. The
52
52
  - `toString()` serializes the MIME type to a string
53
53
  - `isHTML()`: returns true if this instance represents [a HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
54
54
  - `isXML()`: returns true if this instance represents [an XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
55
- - `isJavaScript({ allowParameters })`: returns true if this instance represents [a JavaScript MIME type](https://html.spec.whatwg.org/multipage/scripting.html#javascript-mime-type); `allowParameters` can be set to true to allow arbitrary parameters, instead of their presence causing the method to return `false`
55
+ - `isJavaScript({ prohibitParameters })`: returns true if this instance represents [a JavaScript MIME type](https://html.spec.whatwg.org/multipage/scripting.html#javascript-mime-type). `prohibitParameters` can be set to true to disallow any parameters, i.e. to test if the MIME type's serialization is a [JavaScript MIME type essence match](https://mimesniff.spec.whatwg.org/#javascript-mime-type-essence-match).
56
56
 
57
57
  _Note: the `isHTML()`, `isXML()`, and `isJavaScript()` methods are speculative, and may be removed or changed in future major versions. See [whatwg/mimesniff#48](https://github.com/whatwg/mimesniff/issues/48) for brainstorming in this area. Currently we implement these mainly because they are useful in jsdom._
58
58
 
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ const {
3
+ asciiLowercase,
4
+ solelyContainsHTTPTokenCodePoints,
5
+ soleyContainsHTTPQuotedStringTokenCodePoints
6
+ } = require("./utils.js");
7
+
8
+ module.exports = class MIMETypeParameters {
9
+ constructor(map) {
10
+ this._map = map;
11
+ }
12
+
13
+ get size() {
14
+ return this._map.size;
15
+ }
16
+
17
+ get(name) {
18
+ name = asciiLowercase(String(name));
19
+ return this._map.get(name);
20
+ }
21
+
22
+ has(name) {
23
+ name = asciiLowercase(String(name));
24
+ return this._map.has(name);
25
+ }
26
+
27
+ set(name, value) {
28
+ name = asciiLowercase(String(name));
29
+ value = String(value);
30
+
31
+ if (!solelyContainsHTTPTokenCodePoints(name)) {
32
+ throw new Error(`Invalid MIME type parameter name "${name}": only HTTP token code points are valid.`);
33
+ }
34
+ if (!soleyContainsHTTPQuotedStringTokenCodePoints(value)) {
35
+ throw new Error(`Invalid MIME type parameter value "${value}": only HTTP quoted-string token code points are ` +
36
+ `valid.`);
37
+ }
38
+
39
+ return this._map.set(name, value);
40
+ }
41
+
42
+ clear() {
43
+ this._map.clear();
44
+ }
45
+
46
+ delete(name) {
47
+ name = asciiLowercase(String(name));
48
+ return this._map.delete(name);
49
+ }
50
+
51
+ forEach(callbackFn, thisArg) {
52
+ this._map.forEach(callbackFn, thisArg);
53
+ }
54
+
55
+ keys() {
56
+ return this._map.keys();
57
+ }
58
+
59
+ values() {
60
+ return this._map.values();
61
+ }
62
+
63
+ entries() {
64
+ return this._map.entries();
65
+ }
66
+
67
+ [Symbol.iterator]() {
68
+ return this._map[Symbol.iterator]();
69
+ }
70
+ };
package/lib/mime-type.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
+ const MIMETypeParameters = require("./mime-type-parameters.js");
2
3
  const parse = require("./parser.js");
3
4
  const serialize = require("./serializer.js");
4
5
  const {
5
6
  asciiLowercase,
6
- solelyContainsHTTPTokenCodePoints,
7
- soleyContainsHTTPQuotedStringTokenCodePoints
7
+ solelyContainsHTTPTokenCodePoints
8
8
  } = require("./utils.js");
9
9
 
10
10
  module.exports = class MIMEType {
@@ -76,7 +76,7 @@ module.exports = class MIMEType {
76
76
  return serialize(this);
77
77
  }
78
78
 
79
- isJavaScript({ allowParameters = false } = {}) {
79
+ isJavaScript({ prohibitParameters = false } = {}) {
80
80
  switch (this._type) {
81
81
  case "text": {
82
82
  switch (this._subtype) {
@@ -92,7 +92,7 @@ module.exports = class MIMEType {
92
92
  case "livescript":
93
93
  case "x-ecmascript":
94
94
  case "x-javascript": {
95
- return allowParameters || this._parameters.size === 0;
95
+ return !prohibitParameters || this._parameters.size === 0;
96
96
  }
97
97
  default: {
98
98
  return false;
@@ -105,7 +105,7 @@ module.exports = class MIMEType {
105
105
  case "javascript":
106
106
  case "x-ecmascript":
107
107
  case "x-javascript": {
108
- return allowParameters || this._parameters.size === 0;
108
+ return !prohibitParameters || this._parameters.size === 0;
109
109
  }
110
110
  default: {
111
111
  return false;
@@ -125,67 +125,3 @@ module.exports = class MIMEType {
125
125
  return this._subtype === "html" && this._type === "text";
126
126
  }
127
127
  };
128
-
129
- class MIMETypeParameters {
130
- constructor(map) {
131
- this._map = map;
132
- }
133
-
134
- get size() {
135
- return this._map.size;
136
- }
137
-
138
- get(name) {
139
- name = asciiLowercase(String(name));
140
- return this._map.get(name);
141
- }
142
-
143
- has(name) {
144
- name = asciiLowercase(String(name));
145
- return this._map.has(name);
146
- }
147
-
148
- set(name, value) {
149
- name = asciiLowercase(String(name));
150
- value = String(value);
151
-
152
- if (!solelyContainsHTTPTokenCodePoints(name)) {
153
- throw new Error(`Invalid MIME type parameter name "${name}": only HTTP token code points are valid.`);
154
- }
155
- if (!soleyContainsHTTPQuotedStringTokenCodePoints(value)) {
156
- throw new Error(`Invalid MIME type parameter value "${value}": only HTTP quoted-string token code points are ` +
157
- `valid.`);
158
- }
159
-
160
- return this._map.set(name, value);
161
- }
162
-
163
- clear() {
164
- this._map.clear();
165
- }
166
-
167
- delete(name) {
168
- name = asciiLowercase(String(name));
169
- return this._map.delete(name);
170
- }
171
-
172
- forEach(callbackFn, thisArg) {
173
- this._map.forEach(callbackFn, thisArg);
174
- }
175
-
176
- keys() {
177
- return this._map.keys();
178
- }
179
-
180
- values() {
181
- return this._map.values();
182
- }
183
-
184
- entries() {
185
- return this._map.entries();
186
- }
187
-
188
- [Symbol.iterator]() {
189
- return this._map[Symbol.iterator]();
190
- }
191
- }
package/lib/parser.js CHANGED
@@ -5,7 +5,8 @@ const {
5
5
  isHTTPWhitespaceChar,
6
6
  solelyContainsHTTPTokenCodePoints,
7
7
  soleyContainsHTTPQuotedStringTokenCodePoints,
8
- asciiLowercase
8
+ asciiLowercase,
9
+ collectAnHTTPQuotedString
9
10
  } = require("./utils.js");
10
11
 
11
12
  module.exports = input => {
@@ -71,35 +72,15 @@ module.exports = input => {
71
72
  ++position;
72
73
  }
73
74
 
74
- let parameterValue = "";
75
+ let parameterValue = null;
75
76
  if (input[position] === "\"") {
76
- ++position;
77
-
78
- while (true) {
79
- while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
80
- parameterValue += input[position];
81
- ++position;
82
- }
83
-
84
- if (position < input.length && input[position] === "\\") {
85
- ++position;
86
- if (position < input.length) {
87
- parameterValue += input[position];
88
- ++position;
89
- continue;
90
- } else {
91
- parameterValue += "\\";
92
- break;
93
- }
94
- } else {
95
- break;
96
- }
97
- }
77
+ [parameterValue, position] = collectAnHTTPQuotedString(input, position);
98
78
 
99
79
  while (position < input.length && input[position] !== ";") {
100
80
  ++position;
101
81
  }
102
82
  } else {
83
+ parameterValue = "";
103
84
  while (position < input.length && input[position] !== ";") {
104
85
  parameterValue += input[position];
105
86
  ++position;
package/lib/serializer.js CHANGED
@@ -14,7 +14,7 @@ module.exports = mimeType => {
14
14
  serialization += "=";
15
15
 
16
16
  if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
17
- value = value.replace(/(["\\])/g, "\\$1");
17
+ value = value.replace(/(["\\])/ug, "\\$1");
18
18
  value = `"${value}"`;
19
19
  }
20
20
 
package/lib/utils.js CHANGED
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
 
3
3
  exports.removeLeadingAndTrailingHTTPWhitespace = string => {
4
- return string.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
4
+ return string.replace(/^[ \t\n\r]+/u, "").replace(/[ \t\n\r]+$/u, "");
5
5
  };
6
6
 
7
7
  exports.removeTrailingHTTPWhitespace = string => {
8
- return string.replace(/[ \t\n\r]+$/, "");
8
+ return string.replace(/[ \t\n\r]+$/u, "");
9
9
  };
10
10
 
11
11
  exports.isHTTPWhitespaceChar = char => {
@@ -13,13 +13,48 @@ exports.isHTTPWhitespaceChar = char => {
13
13
  };
14
14
 
15
15
  exports.solelyContainsHTTPTokenCodePoints = string => {
16
- return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/.test(string);
16
+ return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u.test(string);
17
17
  };
18
18
 
19
19
  exports.soleyContainsHTTPQuotedStringTokenCodePoints = string => {
20
- return /^[\t\u0020-\u007E\u0080-\u00FF]*$/.test(string);
20
+ return /^[\t\u0020-\u007E\u0080-\u00FF]*$/u.test(string);
21
21
  };
22
22
 
23
23
  exports.asciiLowercase = string => {
24
- return string.replace(/[A-Z]/g, l => l.toLowerCase());
24
+ return string.replace(/[A-Z]/ug, l => l.toLowerCase());
25
+ };
26
+
27
+ // This variant only implements it with the extract-value flag set.
28
+ exports.collectAnHTTPQuotedString = (input, position) => {
29
+ let value = "";
30
+
31
+ position++;
32
+
33
+ while (true) {
34
+ while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
35
+ value += input[position];
36
+ ++position;
37
+ }
38
+
39
+ if (position >= input.length) {
40
+ break;
41
+ }
42
+
43
+ const quoteOrBackslash = input[position];
44
+ ++position;
45
+
46
+ if (quoteOrBackslash === "\\") {
47
+ if (position >= input.length) {
48
+ value += "\\";
49
+ break;
50
+ }
51
+
52
+ value += input[position];
53
+ ++position;
54
+ } else {
55
+ break;
56
+ }
57
+ }
58
+
59
+ return [value, position];
25
60
  };
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "http",
9
9
  "whatwg"
10
10
  ],
11
- "version": "2.3.0",
11
+ "version": "4.0.0",
12
12
  "author": "Domenic Denicola <d@domenic.me> (https://domenic.me/)",
13
13
  "license": "MIT",
14
14
  "repository": "jsdom/whatwg-mimetype",
@@ -17,27 +17,29 @@
17
17
  "lib/"
18
18
  ],
19
19
  "scripts": {
20
- "test": "jest",
21
- "coverage": "jest --coverage",
20
+ "test": "node --test",
21
+ "coverage": "c8 node --test --experimental-test-coverage",
22
22
  "lint": "eslint .",
23
23
  "pretest": "node scripts/get-latest-platform-tests.js"
24
24
  },
25
25
  "devDependencies": {
26
- "eslint": "^5.9.0",
27
- "jest": "^23.6.0",
26
+ "@domenic/eslint-config": "^3.0.0",
27
+ "c8": "^8.0.1",
28
+ "eslint": "^8.53.0",
28
29
  "printable-string": "^0.3.0",
29
- "request": "^2.88.0",
30
- "whatwg-encoding": "^1.0.5"
30
+ "whatwg-encoding": "^3.0.0"
31
31
  },
32
- "jest": {
33
- "coverageDirectory": "coverage",
34
- "coverageReporters": [
35
- "lcov",
36
- "text-summary"
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "c8": {
36
+ "reporter": [
37
+ "text",
38
+ "html"
37
39
  ],
38
- "testEnvironment": "node",
39
- "testMatch": [
40
- "<rootDir>/test/**/*.js"
40
+ "exclude": [
41
+ "scripts/",
42
+ "test/"
41
43
  ]
42
44
  }
43
45
  }