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 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("content-type-parser");
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
- If the passed string cannot be parsed as a MIME type, the `MIMEType` constructor will throw.
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 `isXML()` 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._
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("content-type-parser/parser");
93
- const serialize = require("content-type-parser/serialize");
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
- removeLeadingAndTrailingASCIIWhitespace,
4
- removeTrailingASCIIWhitespace,
5
- isASCIIWhitespaceChar,
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 = removeLeadingAndTrailingASCIIWhitespace(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 = removeTrailingASCIIWhitespace(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 (isASCIIWhitespaceChar(input[position])) {
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 < input.length) {
76
- if (input[position] === "\"") {
77
- ++position;
75
+ if (input[position] === "\"") {
76
+ ++position;
78
77
 
79
- while (true) {
80
- while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
81
- parameterValue += input[position];
82
- ++position;
83
- }
78
+ while (true) {
79
+ while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
80
+ parameterValue += input[position];
81
+ ++position;
82
+ }
84
83
 
85
- if (position < input.length && input[position] === "\\") {
84
+ if (position < input.length && input[position] === "\\") {
85
+ ++position;
86
+ if (position < input.length) {
87
+ parameterValue += input[position];
86
88
  ++position;
87
- if (position < input.length) {
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
- while (position < input.length && input[position] !== ";") {
101
- ++position;
102
- }
103
- } else {
104
- while (position < input.length && input[position] !== ";") {
105
- parameterValue += input[position];
106
- ++position;
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
- parameterValue = removeTrailingASCIIWhitespace(parameterValue);
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.removeLeadingAndTrailingASCIIWhitespace = string => {
4
- return string.replace(/^[ \t\n\f\r]+/, "").replace(/[ \t\n\f\r]+$/, "");
3
+ exports.removeLeadingAndTrailingHTTPWhitespace = string => {
4
+ return string.replace(/^[ \t\n\r]+/, "").replace(/[ \t\n\r]+$/, "");
5
5
  };
6
6
 
7
- exports.removeTrailingASCIIWhitespace = string => {
8
- return string.replace(/[ \t\n\f\r]+$/, "");
7
+ exports.removeTrailingHTTPWhitespace = string => {
8
+ return string.replace(/[ \t\n\r]+$/, "");
9
9
  };
10
10
 
11
- exports.isASCIIWhitespaceChar = char => {
12
- return char === " " || char === "\t" || char === "\n" || char === "\f" || char === "\r";
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]+$/.test(string);
16
+ return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/.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]*$/.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.0.0",
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": "^4.12.1",
27
- "jest": "^21.2.1",
26
+ "eslint": "^5.9.0",
27
+ "jest": "^23.6.0",
28
28
  "printable-string": "^0.3.0",
29
- "request": "^2.83.0",
30
- "whatwg-encoding": "^1.0.3"
29
+ "request": "^2.88.0",
30
+ "whatwg-encoding": "^1.0.5"
31
31
  },
32
32
  "jest": {
33
33
  "coverageDirectory": "coverage",