whatwg-mimetype 2.0.0 → 2.3.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 +1 -1
- package/README.md +10 -7
- package/lib/mime-type.js +49 -0
- package/lib/parser.js +34 -33
- package/lib/serializer.js +1 -1
- package/lib/utils.js +8 -8
- package/package.json +5 -5
package/LICENSE.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Copyright © 2017 Domenic Denicola <d@domenic.me>
|
|
1
|
+
Copyright © 2017–2018 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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
This package will parse [MIME types](https://mimesniff.spec.whatwg.org/#understanding-mime-types) into a structured format, which can then be manipulated and serialized:
|
|
4
4
|
|
|
5
5
|
```js
|
|
6
|
-
const MIMEType = require("
|
|
6
|
+
const MIMEType = require("whatwg-mimetype");
|
|
7
7
|
|
|
8
8
|
const mimeType = new MIMEType(`Text/HTML;Charset="utf-8"`);
|
|
9
9
|
|
|
@@ -24,14 +24,16 @@ 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
|
-
|
|
28
|
-
|
|
29
|
-
This package's algorithms conform to those of the WHATWG [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/), and is aligned up to commit [cc81ec4](https://github.com/whatwg/mimesniff/commit/cc81ec48288944562c4554069da1d74a71e199fb).
|
|
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).
|
|
30
28
|
|
|
31
29
|
## `MIMEType` API
|
|
32
30
|
|
|
33
31
|
This package's main module's default export is a class, `MIMEType`. Its constructor takes a string which it will attempt to parse into a MIME type; if parsing fails, an `Error` will be thrown.
|
|
34
32
|
|
|
33
|
+
### The `parse()` static factory method
|
|
34
|
+
|
|
35
|
+
As an alternative to the constructor, you can use `MIMEType.parse(string)`. The only difference is that `parse()` will return `null` on failed parsing, whereas the constructor will throw. It thus makes the most sense to use the constructor in cases where unparseable MIME types would be exceptional, and use `parse()` when dealing with input from some unconstrained source.
|
|
36
|
+
|
|
35
37
|
### Properties
|
|
36
38
|
|
|
37
39
|
- `type`: the MIME type's [type](https://mimesniff.spec.whatwg.org/#mime-type-type), e.g. `"text"`
|
|
@@ -50,8 +52,9 @@ This package's main module's default export is a class, `MIMEType`. Its construc
|
|
|
50
52
|
- `toString()` serializes the MIME type to a string
|
|
51
53
|
- `isHTML()`: returns true if this instance represents [a HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
|
|
52
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`
|
|
53
56
|
|
|
54
|
-
_Note: the `isHTML()` and `
|
|
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._
|
|
55
58
|
|
|
56
59
|
## `MIMETypeParameters` API
|
|
57
60
|
|
|
@@ -89,8 +92,8 @@ mimeType.parameters.set("@", "x");
|
|
|
89
92
|
If you want primitives on which to build your own API, you can get direct access to the parsing and serialization algorithms as follows:
|
|
90
93
|
|
|
91
94
|
```js
|
|
92
|
-
const parse = require("
|
|
93
|
-
const serialize = require("
|
|
95
|
+
const parse = require("whatwg-mimetype/parser");
|
|
96
|
+
const serialize = require("whatwg-mimetype/serialize");
|
|
94
97
|
```
|
|
95
98
|
|
|
96
99
|
`parse(string)` returns an object containing the `type` and `subtype` strings, plus `parameters`, which is a `Map`. This is roughly our equivalent of the spec's [MIME type record](https://mimesniff.spec.whatwg.org/#mime-type). If parsing fails, it instead returns `null`.
|
package/lib/mime-type.js
CHANGED
|
@@ -20,6 +20,14 @@ module.exports = class MIMEType {
|
|
|
20
20
|
this._parameters = new MIMETypeParameters(result.parameters);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
static parse(string) {
|
|
24
|
+
try {
|
|
25
|
+
return new this(string);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
get essence() {
|
|
24
32
|
return `${this.type}/${this.subtype}`;
|
|
25
33
|
}
|
|
@@ -68,6 +76,47 @@ module.exports = class MIMEType {
|
|
|
68
76
|
return serialize(this);
|
|
69
77
|
}
|
|
70
78
|
|
|
79
|
+
isJavaScript({ allowParameters = false } = {}) {
|
|
80
|
+
switch (this._type) {
|
|
81
|
+
case "text": {
|
|
82
|
+
switch (this._subtype) {
|
|
83
|
+
case "ecmascript":
|
|
84
|
+
case "javascript":
|
|
85
|
+
case "javascript1.0":
|
|
86
|
+
case "javascript1.1":
|
|
87
|
+
case "javascript1.2":
|
|
88
|
+
case "javascript1.3":
|
|
89
|
+
case "javascript1.4":
|
|
90
|
+
case "javascript1.5":
|
|
91
|
+
case "jscript":
|
|
92
|
+
case "livescript":
|
|
93
|
+
case "x-ecmascript":
|
|
94
|
+
case "x-javascript": {
|
|
95
|
+
return allowParameters || this._parameters.size === 0;
|
|
96
|
+
}
|
|
97
|
+
default: {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
case "application": {
|
|
103
|
+
switch (this._subtype) {
|
|
104
|
+
case "ecmascript":
|
|
105
|
+
case "javascript":
|
|
106
|
+
case "x-ecmascript":
|
|
107
|
+
case "x-javascript": {
|
|
108
|
+
return allowParameters || this._parameters.size === 0;
|
|
109
|
+
}
|
|
110
|
+
default: {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
default: {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
71
120
|
isXML() {
|
|
72
121
|
return (this._subtype === "xml" && (this._type === "text" || this._type === "application")) ||
|
|
73
122
|
this._subtype.endsWith("+xml");
|
package/lib/parser.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
removeLeadingAndTrailingHTTPWhitespace,
|
|
4
|
+
removeTrailingHTTPWhitespace,
|
|
5
|
+
isHTTPWhitespaceChar,
|
|
6
6
|
solelyContainsHTTPTokenCodePoints,
|
|
7
7
|
soleyContainsHTTPQuotedStringTokenCodePoints,
|
|
8
8
|
asciiLowercase
|
|
9
9
|
} = require("./utils.js");
|
|
10
10
|
|
|
11
11
|
module.exports = input => {
|
|
12
|
-
input =
|
|
12
|
+
input = removeLeadingAndTrailingHTTPWhitespace(input);
|
|
13
13
|
|
|
14
14
|
let position = 0;
|
|
15
15
|
let type = "";
|
|
@@ -35,7 +35,7 @@ module.exports = input => {
|
|
|
35
35
|
++position;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
subtype =
|
|
38
|
+
subtype = removeTrailingHTTPWhitespace(subtype);
|
|
39
39
|
|
|
40
40
|
if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
|
|
41
41
|
return null;
|
|
@@ -51,7 +51,7 @@ module.exports = input => {
|
|
|
51
51
|
// Skip past ";"
|
|
52
52
|
++position;
|
|
53
53
|
|
|
54
|
-
while (
|
|
54
|
+
while (isHTTPWhitespaceChar(input[position])) {
|
|
55
55
|
++position;
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -72,46 +72,47 @@ module.exports = input => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
let parameterValue = "";
|
|
75
|
-
if (position
|
|
76
|
-
|
|
77
|
-
++position;
|
|
75
|
+
if (input[position] === "\"") {
|
|
76
|
+
++position;
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
while (true) {
|
|
79
|
+
while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
|
|
80
|
+
parameterValue += input[position];
|
|
81
|
+
++position;
|
|
82
|
+
}
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
if (position < input.length && input[position] === "\\") {
|
|
85
|
+
++position;
|
|
86
|
+
if (position < input.length) {
|
|
87
|
+
parameterValue += input[position];
|
|
86
88
|
++position;
|
|
87
|
-
|
|
88
|
-
parameterValue += input[position];
|
|
89
|
-
++position;
|
|
90
|
-
continue;
|
|
91
|
-
} else {
|
|
92
|
-
parameterValue += "\\";
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
89
|
+
continue;
|
|
95
90
|
} else {
|
|
91
|
+
parameterValue += "\\";
|
|
96
92
|
break;
|
|
97
93
|
}
|
|
94
|
+
} else {
|
|
95
|
+
break;
|
|
98
96
|
}
|
|
97
|
+
}
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
99
|
+
while (position < input.length && input[position] !== ";") {
|
|
100
|
+
++position;
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
while (position < input.length && input[position] !== ";") {
|
|
104
|
+
parameterValue += input[position];
|
|
105
|
+
++position;
|
|
106
|
+
}
|
|
108
107
|
|
|
109
|
-
|
|
108
|
+
parameterValue = removeTrailingHTTPWhitespace(parameterValue);
|
|
109
|
+
|
|
110
|
+
if (parameterValue === "") {
|
|
111
|
+
continue;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
if (parameterName.length > 0 &&
|
|
114
|
-
parameterValue.length > 0 &&
|
|
115
116
|
solelyContainsHTTPTokenCodePoints(parameterName) &&
|
|
116
117
|
soleyContainsHTTPQuotedStringTokenCodePoints(parameterValue) &&
|
|
117
118
|
!mimeType.parameters.has(parameterName)) {
|
package/lib/serializer.js
CHANGED
|
@@ -13,7 +13,7 @@ module.exports = mimeType => {
|
|
|
13
13
|
serialization += name;
|
|
14
14
|
serialization += "=";
|
|
15
15
|
|
|
16
|
-
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
16
|
+
if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
|
|
17
17
|
value = value.replace(/(["\\])/g, "\\$1");
|
|
18
18
|
value = `"${value}"`;
|
|
19
19
|
}
|
package/lib/utils.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
exports.
|
|
4
|
-
return string.replace(/^[ \t\n\
|
|
3
|
+
exports.removeLeadingAndTrailingHTTPWhitespace = string => {
|
|
4
|
+
return string.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
|
|
5
5
|
};
|
|
6
6
|
|
|
7
|
-
exports.
|
|
8
|
-
return string.replace(/[ \t\n\
|
|
7
|
+
exports.removeTrailingHTTPWhitespace = string => {
|
|
8
|
+
return string.replace(/[ \t\n\r]+$/, "");
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
exports.
|
|
12
|
-
return char === " " || char === "\t" || char === "\n" || char === "\
|
|
11
|
+
exports.isHTTPWhitespaceChar = char => {
|
|
12
|
+
return char === " " || char === "\t" || char === "\n" || char === "\r";
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
exports.solelyContainsHTTPTokenCodePoints = string => {
|
|
16
|
-
return /^[-!#$%&'*+.^_`|~A-Za-z0-9]
|
|
16
|
+
return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/.test(string);
|
|
17
17
|
};
|
|
18
18
|
|
|
19
19
|
exports.soleyContainsHTTPQuotedStringTokenCodePoints = string => {
|
|
20
|
-
return /^[\t\u0020-\u007E\u0080-\u00FF]
|
|
20
|
+
return /^[\t\u0020-\u007E\u0080-\u00FF]*$/.test(string);
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
exports.asciiLowercase = string => {
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"http",
|
|
9
9
|
"whatwg"
|
|
10
10
|
],
|
|
11
|
-
"version": "2.
|
|
11
|
+
"version": "2.3.0",
|
|
12
12
|
"author": "Domenic Denicola <d@domenic.me> (https://domenic.me/)",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"repository": "jsdom/whatwg-mimetype",
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
"pretest": "node scripts/get-latest-platform-tests.js"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"eslint": "^
|
|
27
|
-
"jest": "^
|
|
26
|
+
"eslint": "^5.9.0",
|
|
27
|
+
"jest": "^23.6.0",
|
|
28
28
|
"printable-string": "^0.3.0",
|
|
29
|
-
"request": "^2.
|
|
30
|
-
"whatwg-encoding": "^1.0.
|
|
29
|
+
"request": "^2.88.0",
|
|
30
|
+
"whatwg-encoding": "^1.0.5"
|
|
31
31
|
},
|
|
32
32
|
"jest": {
|
|
33
33
|
"coverageDirectory": "coverage",
|