@d1g1tal/media-type 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 +7 -0
- package/README.md +103 -0
- package/dist/media-type.js +304 -0
- package/dist/media-type.min.js +4 -0
- package/dist/media-type.min.js.map +7 -0
- package/index.d.ts +5 -0
- package/index.js +5 -0
- package/package.json +88 -0
- package/src/media-type-parameters.d.ts +91 -0
- package/src/media-type-parameters.js +141 -0
- package/src/media-type.d.ts +91 -0
- package/src/media-type.js +188 -0
- package/src/parser.d.ts +13 -0
- package/src/parser.js +109 -0
- package/src/serializer.d.ts +11 -0
- package/src/serializer.js +35 -0
- package/src/utils.d.ts +52 -0
- package/src/utils.js +93 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright © Domenic Denicola <d@domenic.me>
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Parse, serialize, and manipulate media types
|
|
2
|
+
|
|
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
|
+
|
|
5
|
+
This version is using ES Modules instead of commonJS.
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import { MediaType } from '@d1g1tal/mime-type';
|
|
9
|
+
|
|
10
|
+
const mediaType = new MediaType(`Text/HTML;Charset="utf-8"`);
|
|
11
|
+
|
|
12
|
+
console.assert(mediaType.toString() === "text/html;charset=utf-8");
|
|
13
|
+
|
|
14
|
+
console.assert(mediaType.type === "text");
|
|
15
|
+
console.assert(mediaType.subtype === "html");
|
|
16
|
+
console.assert(mediaType.essence === "text/html");
|
|
17
|
+
console.assert(mediaType.parameters.get("charset") === "utf-8");
|
|
18
|
+
|
|
19
|
+
mediaType.parameters.set("charset", "windows-1252");
|
|
20
|
+
console.assert(mediaType.parameters.get("charset") === "windows-1252");
|
|
21
|
+
console.assert(mediaType.toString() === "text/html;charset=windows-1252");
|
|
22
|
+
|
|
23
|
+
console.assert(mediaType.isHTML() === true);
|
|
24
|
+
console.assert(mediaType.isXML() === false);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
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)).
|
|
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 [8e9a7dd](https://github.com/whatwg/mimesniff/commit/8e9a7dd90717c595a4e4d982cd216e4411d33736).
|
|
30
|
+
|
|
31
|
+
## `MediaType` API
|
|
32
|
+
|
|
33
|
+
This package's main module's export is a class, `MediaType`. Its constructor takes a string which it will attempt to parse into a media type; if parsing fails, an `Error` will be thrown.
|
|
34
|
+
|
|
35
|
+
### The `parse()` static factory method
|
|
36
|
+
|
|
37
|
+
As an alternative to the constructor, you can use `MediaType.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 unparsable MIME types would be exceptional, and use `parse()` when dealing with input from some unconstrained source.
|
|
38
|
+
|
|
39
|
+
### Properties
|
|
40
|
+
|
|
41
|
+
- `type`: the media type's [type](https://mimesniff.spec.whatwg.org/#mime-type-type), e.g. `"text"`
|
|
42
|
+
- `subtype`: the media type's [subtype](https://mimesniff.spec.whatwg.org/#mime-type-subtype), e.g. `"html"`
|
|
43
|
+
- `essence`: the media type's [essence](https://mimesniff.spec.whatwg.org/#mime-type-essence), e.g. `"text/html"`
|
|
44
|
+
- `parameters`: an instance of `MediaTypeParameters`, containing this media type's [parameters](https://mimesniff.spec.whatwg.org/#mime-type-parameters)
|
|
45
|
+
|
|
46
|
+
`type` and `subtype` can be changed. They will be validated to be non-empty and only contain [HTTP token code points](https://mimesniff.spec.whatwg.org/#http-token-code-point).
|
|
47
|
+
|
|
48
|
+
`essence` is only a getter, and cannot be changed.
|
|
49
|
+
|
|
50
|
+
`parameters` is also a getter, but the contents of the `MediaTypeParameters` object are mutable, as described below.
|
|
51
|
+
|
|
52
|
+
### Methods
|
|
53
|
+
|
|
54
|
+
- `toString()` serializes the media type to a string
|
|
55
|
+
- `isHTML()`: returns true if this instance represents [a HTML media type](https://mimesniff.spec.whatwg.org/#html-mime-type)
|
|
56
|
+
- `isXML()`: returns true if this instance represents [an XML media type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
|
|
57
|
+
- `isJavaScript({ prohibitParameters })`: returns true if this instance represents [a JavaScript media 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 media type's serialization is a [JavaScript media type essence match](https://mimesniff.spec.whatwg.org/#javascript-mime-type-essence-match).
|
|
58
|
+
|
|
59
|
+
_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._
|
|
60
|
+
|
|
61
|
+
## `MediaTypeParameters` API
|
|
62
|
+
|
|
63
|
+
The `MediaTypeParameters` class, instances of which are returned by `MediaType.parameters`, has equivalent surface API to a [JavaScript `Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).
|
|
64
|
+
|
|
65
|
+
However, `MediaTypeParameters` methods will always interpret their arguments as appropriate for media types, so e.g. parameter names will be lowercased, and attempting to set invalid characters will throw.
|
|
66
|
+
|
|
67
|
+
Some examples:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
const mediaType = new MediaType(`x/x;a=b;c=D;E="F"`);
|
|
71
|
+
|
|
72
|
+
// Logs:
|
|
73
|
+
// a b
|
|
74
|
+
// c D
|
|
75
|
+
// e F
|
|
76
|
+
for (const [name, value] of mediaType.parameters) {
|
|
77
|
+
console.log(name, value);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
console.assert(mediaType.parameters.has("a"));
|
|
81
|
+
console.assert(mediaType.parameters.has("A"));
|
|
82
|
+
console.assert(mediaType.parameters.get("A") === "b");
|
|
83
|
+
|
|
84
|
+
mediaType.parameters.set("Q", "X");
|
|
85
|
+
console.assert(mediaType.parameters.get("q") === "X");
|
|
86
|
+
console.assert(mediaType.toString() === "x/x;a=b;c=d;e=F;q=X");
|
|
87
|
+
|
|
88
|
+
// Throws:
|
|
89
|
+
mediaType.parameters.set("@", "x");
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Raw parsing/serialization APIs
|
|
93
|
+
|
|
94
|
+
If you want primitives on which to build your own API, you can get direct access to the parsing and serialization algorithms as follows:
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
import { parse } from '@d1g1tal/media-type';
|
|
98
|
+
import { serialize } from '@d1g1tal/media-type';
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`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`.
|
|
102
|
+
|
|
103
|
+
`serialize(record)` operates on the such an object, giving back a string according to the serialization algorithm.
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
var MediaType = (() => {
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/media-type.js
|
|
21
|
+
var media_type_exports = {};
|
|
22
|
+
__export(media_type_exports, {
|
|
23
|
+
default: () => MediaType
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// src/utils.js
|
|
27
|
+
var removeLeadingAndTrailingHTTPWhitespace = (string) => string.replace(/^[ \t\n\r]+/u, "").replace(/[ \t\n\r]+$/u, "");
|
|
28
|
+
var removeTrailingHTTPWhitespace = (string) => string.replace(/[ \t\n\r]+$/u, "");
|
|
29
|
+
var isHTTPWhitespaceChar = (char) => char === " " || char === " " || char === "\n" || char === "\r";
|
|
30
|
+
var solelyContainsHTTPTokenCodePoints = (string) => /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u.test(string);
|
|
31
|
+
var solelyContainsHTTPQuotedStringTokenCodePoints = (string) => /^[\t\u0020-\u007E\u0080-\u00FF]*$/u.test(string);
|
|
32
|
+
var asciiLowercase = (string) => string.replace(/[A-Z]/ug, (l) => l.toLowerCase());
|
|
33
|
+
var collectAnHTTPQuotedString = (input, position) => {
|
|
34
|
+
let value = "";
|
|
35
|
+
position++;
|
|
36
|
+
while (true) {
|
|
37
|
+
while (position < input.length && input[position] !== '"' && input[position] !== "\\") {
|
|
38
|
+
value += input[position];
|
|
39
|
+
++position;
|
|
40
|
+
}
|
|
41
|
+
if (position >= input.length) {
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
const quoteOrBackslash = input[position];
|
|
45
|
+
++position;
|
|
46
|
+
if (quoteOrBackslash === "\\") {
|
|
47
|
+
if (position >= input.length) {
|
|
48
|
+
value += "\\";
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
value += input[position];
|
|
52
|
+
++position;
|
|
53
|
+
} else {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return [value, position];
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// src/media-type-parameters.js
|
|
61
|
+
var MediaTypeParameters = class {
|
|
62
|
+
constructor(map) {
|
|
63
|
+
this._map = map;
|
|
64
|
+
}
|
|
65
|
+
get size() {
|
|
66
|
+
return this._map.size;
|
|
67
|
+
}
|
|
68
|
+
get(name) {
|
|
69
|
+
return this._map.get(asciiLowercase(String(name)));
|
|
70
|
+
}
|
|
71
|
+
has(name) {
|
|
72
|
+
return this._map.has(asciiLowercase(String(name)));
|
|
73
|
+
}
|
|
74
|
+
set(name, value) {
|
|
75
|
+
name = asciiLowercase(String(name));
|
|
76
|
+
value = String(value);
|
|
77
|
+
if (!solelyContainsHTTPTokenCodePoints(name)) {
|
|
78
|
+
throw new Error(`Invalid MIME type parameter name "${name}": only HTTP token code points are valid.`);
|
|
79
|
+
}
|
|
80
|
+
if (!solelyContainsHTTPQuotedStringTokenCodePoints(value)) {
|
|
81
|
+
throw new Error(`Invalid MIME type parameter value "${value}": only HTTP quoted-string token code points are valid.`);
|
|
82
|
+
}
|
|
83
|
+
this._map.set(name, value);
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
clear() {
|
|
87
|
+
this._map.clear();
|
|
88
|
+
}
|
|
89
|
+
delete(name) {
|
|
90
|
+
name = asciiLowercase(String(name));
|
|
91
|
+
return this._map.delete(name);
|
|
92
|
+
}
|
|
93
|
+
forEach(callback, thisArg) {
|
|
94
|
+
this._map.forEach(callback, thisArg);
|
|
95
|
+
}
|
|
96
|
+
keys() {
|
|
97
|
+
return this._map.keys();
|
|
98
|
+
}
|
|
99
|
+
values() {
|
|
100
|
+
return this._map.values();
|
|
101
|
+
}
|
|
102
|
+
entries() {
|
|
103
|
+
return this._map.entries();
|
|
104
|
+
}
|
|
105
|
+
[Symbol.iterator]() {
|
|
106
|
+
return this._map[Symbol.iterator]();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/parser.js
|
|
111
|
+
var parse = (input) => {
|
|
112
|
+
input = removeLeadingAndTrailingHTTPWhitespace(input);
|
|
113
|
+
let position = 0;
|
|
114
|
+
let type = "";
|
|
115
|
+
while (position < input.length && input[position] !== "/") {
|
|
116
|
+
type += input[position];
|
|
117
|
+
++position;
|
|
118
|
+
}
|
|
119
|
+
if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
if (position >= input.length) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
++position;
|
|
126
|
+
let subtype = "";
|
|
127
|
+
while (position < input.length && input[position] !== ";") {
|
|
128
|
+
subtype += input[position];
|
|
129
|
+
++position;
|
|
130
|
+
}
|
|
131
|
+
subtype = removeTrailingHTTPWhitespace(subtype);
|
|
132
|
+
if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
const mediaType = {
|
|
136
|
+
type: asciiLowercase(type),
|
|
137
|
+
subtype: asciiLowercase(subtype),
|
|
138
|
+
parameters: /* @__PURE__ */ new Map()
|
|
139
|
+
};
|
|
140
|
+
while (position < input.length) {
|
|
141
|
+
++position;
|
|
142
|
+
while (isHTTPWhitespaceChar(input[position])) {
|
|
143
|
+
++position;
|
|
144
|
+
}
|
|
145
|
+
let parameterName = "";
|
|
146
|
+
while (position < input.length && input[position] !== ";" && input[position] !== "=") {
|
|
147
|
+
parameterName += input[position];
|
|
148
|
+
++position;
|
|
149
|
+
}
|
|
150
|
+
parameterName = asciiLowercase(parameterName);
|
|
151
|
+
if (position < input.length) {
|
|
152
|
+
if (input[position] === ";") {
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
++position;
|
|
156
|
+
}
|
|
157
|
+
let parameterValue = null;
|
|
158
|
+
if (input[position] === '"') {
|
|
159
|
+
[parameterValue, position] = collectAnHTTPQuotedString(input, position);
|
|
160
|
+
while (position < input.length && input[position] !== ";") {
|
|
161
|
+
++position;
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
parameterValue = "";
|
|
165
|
+
while (position < input.length && input[position] !== ";") {
|
|
166
|
+
parameterValue += input[position];
|
|
167
|
+
++position;
|
|
168
|
+
}
|
|
169
|
+
parameterValue = removeTrailingHTTPWhitespace(parameterValue);
|
|
170
|
+
if (parameterValue === "") {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (parameterName.length > 0 && solelyContainsHTTPTokenCodePoints(parameterName) && solelyContainsHTTPQuotedStringTokenCodePoints(parameterValue) && !mediaType.parameters.has(parameterName)) {
|
|
175
|
+
mediaType.parameters.set(parameterName, parameterValue);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return mediaType;
|
|
179
|
+
};
|
|
180
|
+
var parser_default = parse;
|
|
181
|
+
|
|
182
|
+
// src/serializer.js
|
|
183
|
+
var serialize = (mediaType) => {
|
|
184
|
+
let serialization = `${mediaType.type}/${mediaType.subtype}`;
|
|
185
|
+
if (mediaType.parameters.size === 0) {
|
|
186
|
+
return serialization;
|
|
187
|
+
}
|
|
188
|
+
for (let [name, value] of mediaType.parameters) {
|
|
189
|
+
serialization += ";";
|
|
190
|
+
serialization += name;
|
|
191
|
+
serialization += "=";
|
|
192
|
+
if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
|
|
193
|
+
value = value.replace(/(["\\])/ug, "\\$1");
|
|
194
|
+
value = `"${value}"`;
|
|
195
|
+
}
|
|
196
|
+
serialization += value;
|
|
197
|
+
}
|
|
198
|
+
return serialization;
|
|
199
|
+
};
|
|
200
|
+
var serializer_default = serialize;
|
|
201
|
+
|
|
202
|
+
// src/media-type.js
|
|
203
|
+
var MediaType = class {
|
|
204
|
+
constructor(string) {
|
|
205
|
+
string = String(string);
|
|
206
|
+
const result = parser_default(string);
|
|
207
|
+
if (result === null) {
|
|
208
|
+
throw new Error(`Could not parse media type string '${string}'`);
|
|
209
|
+
}
|
|
210
|
+
this._type = result.type;
|
|
211
|
+
this._subtype = result.subtype;
|
|
212
|
+
this._parameters = new MediaTypeParameters(result.parameters);
|
|
213
|
+
}
|
|
214
|
+
static parse(string) {
|
|
215
|
+
try {
|
|
216
|
+
return new this(string);
|
|
217
|
+
} catch (e) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
get essence() {
|
|
222
|
+
return `${this.type}/${this.subtype}`;
|
|
223
|
+
}
|
|
224
|
+
get type() {
|
|
225
|
+
return this._type;
|
|
226
|
+
}
|
|
227
|
+
set type(value) {
|
|
228
|
+
value = asciiLowercase(String(value));
|
|
229
|
+
if (value.length === 0) {
|
|
230
|
+
throw new Error("Invalid type: must be a non-empty string");
|
|
231
|
+
}
|
|
232
|
+
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
233
|
+
throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
|
|
234
|
+
}
|
|
235
|
+
this._type = value;
|
|
236
|
+
}
|
|
237
|
+
get subtype() {
|
|
238
|
+
return this._subtype;
|
|
239
|
+
}
|
|
240
|
+
set subtype(value) {
|
|
241
|
+
value = asciiLowercase(String(value));
|
|
242
|
+
if (value.length === 0) {
|
|
243
|
+
throw new Error("Invalid subtype: must be a non-empty string");
|
|
244
|
+
}
|
|
245
|
+
if (!solelyContainsHTTPTokenCodePoints(value)) {
|
|
246
|
+
throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
|
|
247
|
+
}
|
|
248
|
+
this._subtype = value;
|
|
249
|
+
}
|
|
250
|
+
get parameters() {
|
|
251
|
+
return this._parameters;
|
|
252
|
+
}
|
|
253
|
+
toString() {
|
|
254
|
+
return serializer_default(this);
|
|
255
|
+
}
|
|
256
|
+
isJavaScript({ prohibitParameters = false } = {}) {
|
|
257
|
+
switch (this._type) {
|
|
258
|
+
case "text": {
|
|
259
|
+
switch (this._subtype) {
|
|
260
|
+
case "ecmascript":
|
|
261
|
+
case "javascript":
|
|
262
|
+
case "javascript1.0":
|
|
263
|
+
case "javascript1.1":
|
|
264
|
+
case "javascript1.2":
|
|
265
|
+
case "javascript1.3":
|
|
266
|
+
case "javascript1.4":
|
|
267
|
+
case "javascript1.5":
|
|
268
|
+
case "jscript":
|
|
269
|
+
case "livescript":
|
|
270
|
+
case "x-ecmascript":
|
|
271
|
+
case "x-javascript":
|
|
272
|
+
return !prohibitParameters || this._parameters.size === 0;
|
|
273
|
+
default:
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
case "application": {
|
|
278
|
+
switch (this._subtype) {
|
|
279
|
+
case "ecmascript":
|
|
280
|
+
case "javascript":
|
|
281
|
+
case "x-ecmascript":
|
|
282
|
+
case "x-javascript":
|
|
283
|
+
return !prohibitParameters || this._parameters.size === 0;
|
|
284
|
+
default:
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
default:
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
isXML() {
|
|
293
|
+
return this._subtype === "xml" && (this._type === "text" || this._type === "application") || this._subtype.endsWith("+xml");
|
|
294
|
+
}
|
|
295
|
+
isHTML() {
|
|
296
|
+
return this._subtype === "html" && this._type === "text";
|
|
297
|
+
}
|
|
298
|
+
get [Symbol.toStringTag]() {
|
|
299
|
+
return "MediaType";
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
return __toCommonJS(media_type_exports);
|
|
303
|
+
})();
|
|
304
|
+
window.MediaType = MediaType.default;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var MediaType=(()=>{var m=Object.defineProperty;var w=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var b=(t,e)=>{for(var r in e)m(t,r,{get:e[r],enumerable:!0})},H=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of _(e))!P.call(t,n)&&n!==r&&m(t,n,{get:()=>e[n],enumerable:!(s=w(e,n))||s.enumerable});return t};var C=t=>H(m({},"__esModule",{value:!0}),t);var $={};b($,{default:()=>p});var u=t=>t.replace(/^[ \t\n\r]+/u,"").replace(/[ \t\n\r]+$/u,""),y=t=>t.replace(/[ \t\n\r]+$/u,""),T=t=>t===" "||t===" "||t===`
|
|
2
|
+
`||t==="\r",i=t=>/^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u.test(t),h=t=>/^[\t\u0020-\u007E\u0080-\u00FF]*$/u.test(t),a=t=>t.replace(/[A-Z]/ug,e=>e.toLowerCase()),g=(t,e)=>{let r="";for(e++;;){for(;e<t.length&&t[e]!=='"'&&t[e]!=="\\";)r+=t[e],++e;if(e>=t.length)break;let s=t[e];if(++e,s==="\\"){if(e>=t.length){r+="\\";break}r+=t[e],++e}else break}return[r,e]};var c=class{constructor(e){this._map=e}get size(){return this._map.size}get(e){return this._map.get(a(String(e)))}has(e){return this._map.has(a(String(e)))}set(e,r){if(e=a(String(e)),r=String(r),!i(e))throw new Error(`Invalid MIME type parameter name "${e}": only HTTP token code points are valid.`);if(!h(r))throw new Error(`Invalid MIME type parameter value "${r}": only HTTP quoted-string token code points are valid.`);return this._map.set(e,r),this}clear(){this._map.clear()}delete(e){return e=a(String(e)),this._map.delete(e)}forEach(e,r){this._map.forEach(e,r)}keys(){return this._map.keys()}values(){return this._map.values()}entries(){return this._map.entries()}[Symbol.iterator](){return this._map[Symbol.iterator]()}};var S=t=>{t=u(t);let e=0,r="";for(;e<t.length&&t[e]!=="/";)r+=t[e],++e;if(r.length===0||!i(r)||e>=t.length)return null;++e;let s="";for(;e<t.length&&t[e]!==";";)s+=t[e],++e;if(s=y(s),s.length===0||!i(s))return null;let n={type:a(r),subtype:a(s),parameters:new Map};for(;e<t.length;){for(++e;T(t[e]);)++e;let l="";for(;e<t.length&&t[e]!==";"&&t[e]!=="=";)l+=t[e],++e;if(l=a(l),e<t.length){if(t[e]===";")continue;++e}let o=null;if(t[e]==='"')for([o,e]=g(t,e);e<t.length&&t[e]!==";";)++e;else{for(o="";e<t.length&&t[e]!==";";)o+=t[e],++e;if(o=y(o),o==="")continue}l.length>0&&i(l)&&h(o)&&!n.parameters.has(l)&&n.parameters.set(l,o)}return n},f=S;var k=t=>{let e=`${t.type}/${t.subtype}`;if(t.parameters.size===0)return e;for(let[r,s]of t.parameters)e+=";",e+=r,e+="=",(!i(s)||s.length===0)&&(s=s.replace(/(["\\])/ug,"\\$1"),s=`"${s}"`),e+=s;return e},d=k;var p=class{constructor(e){e=String(e);let r=f(e);if(r===null)throw new Error(`Could not parse media type string '${e}'`);this._type=r.type,this._subtype=r.subtype,this._parameters=new c(r.parameters)}static parse(e){try{return new this(e)}catch{return null}}get essence(){return`${this.type}/${this.subtype}`}get type(){return this._type}set type(e){if(e=a(String(e)),e.length===0)throw new Error("Invalid type: must be a non-empty string");if(!i(e))throw new Error(`Invalid type ${e}: must contain only HTTP token code points`);this._type=e}get subtype(){return this._subtype}set subtype(e){if(e=a(String(e)),e.length===0)throw new Error("Invalid subtype: must be a non-empty string");if(!i(e))throw new Error(`Invalid subtype ${e}: must contain only HTTP token code points`);this._subtype=e}get parameters(){return this._parameters}toString(){return d(this)}isJavaScript({prohibitParameters:e=!1}={}){switch(this._type){case"text":switch(this._subtype){case"ecmascript":case"javascript":case"javascript1.0":case"javascript1.1":case"javascript1.2":case"javascript1.3":case"javascript1.4":case"javascript1.5":case"jscript":case"livescript":case"x-ecmascript":case"x-javascript":return!e||this._parameters.size===0;default:return!1}case"application":switch(this._subtype){case"ecmascript":case"javascript":case"x-ecmascript":case"x-javascript":return!e||this._parameters.size===0;default:return!1}default:return!1}}isXML(){return this._subtype==="xml"&&(this._type==="text"||this._type==="application")||this._subtype.endsWith("+xml")}isHTML(){return this._subtype==="html"&&this._type==="text"}get[Symbol.toStringTag](){return"MediaType"}};return C($);})();
|
|
3
|
+
window.MediaType = MediaType.default;
|
|
4
|
+
//# sourceMappingURL=media-type.min.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/media-type.js", "../src/utils.js", "../src/media-type-parameters.js", "../src/parser.js", "../src/serializer.js"],
|
|
4
|
+
"sourcesContent": ["import MediaTypeParameters from './media-type-parameters.js';\nimport parse from './parser.js';\nimport serialize from './serializer.js';\nimport { asciiLowercase, solelyContainsHTTPTokenCodePoints } from './utils.js';\n\n/**\n * Class used to parse media types.\n *\n * @see https://mimesniff.spec.whatwg.org/#understanding-mime-types\n * @module MediaType\n */\nexport default class MediaType {\n\t/**\n\t * Create a new MediaType instance from a string representation.\n\t *\n\t * @param {string} string The media type to parse\n\t */\n\tconstructor(string) {\n\t\tstring = String(string);\n\t\tconst result = parse(string);\n\t\tif (result === null) {\n\t\t\tthrow new Error(`Could not parse media type string '${string}'`);\n\t\t}\n\n\t\tthis._type = result.type;\n\t\tthis._subtype = result.subtype;\n\t\tthis._parameters = new MediaTypeParameters(result.parameters);\n\t}\n\n\t/**\n\t * Static factor method for parsing a media type.\n\t *\n\t * @param {string} string The media type to parse\n\t * @returns {MediaType} The parsed {@link MediaType} object\n\t */\n\tstatic parse(string) {\n\t\ttry {\n\t\t\treturn new this(string);\n\t\t} catch (e) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Gets the media type essence (type/subtype).\n\t *\n\t * @returns {string} The media type without any parameters\n\t */\n\tget essence() {\n\t\treturn `${this.type}/${this.subtype}`;\n\t}\n\n\t/**\n\t * Gets the type.\n\t *\n\t * @returns {string} The type.\n\t */\n\tget type() {\n\t\treturn this._type;\n\t}\n\n\t/**\n\t * Sets the type.\n\t */\n\tset type(value) {\n\t\tvalue = asciiLowercase(String(value));\n\n\t\tif (value.length === 0) {\n\t\t\tthrow new Error('Invalid type: must be a non-empty string');\n\t\t}\n\t\tif (!solelyContainsHTTPTokenCodePoints(value)) {\n\t\t\tthrow new Error(`Invalid type ${value}: must contain only HTTP token code points`);\n\t\t}\n\n\t\tthis._type = value;\n\t}\n\n\t/**\n\t * Gets the subtype.\n\t *\n\t * @returns {string} The subtype.\n\t */\n\tget subtype() {\n\t\treturn this._subtype;\n\t}\n\n\t/**\n\t * Sets the subtype.\n\t */\n\tset subtype(value) {\n\t\tvalue = asciiLowercase(String(value));\n\n\t\tif (value.length === 0) {\n\t\t\tthrow new Error('Invalid subtype: must be a non-empty string');\n\t\t}\n\t\tif (!solelyContainsHTTPTokenCodePoints(value)) {\n\t\t\tthrow new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);\n\t\t}\n\n\t\tthis._subtype = value;\n\t}\n\n\t/**\n\t * Gets the parameters.\n\t *\n\t * @returns {MediaTypeParameters} The media type parameters.\n\t */\n\tget parameters() {\n\t\treturn this._parameters;\n\t}\n\n\t/**\n\t * Gets the serialized version of the media type.\n\t *\n\t * @returns {string} The serialized media type.\n\t */\n\ttoString() {\n\t\t// The serialize function works on both 'media type records' (i.e. the results of parse) and on this class, since\n\t\t// this class's interface is identical.\n\t\treturn serialize(this);\n\t}\n\n\t/**\n\t * Determines if this instance is a JavaScript media type.\n\t *\n\t * @param {Object} [options] Optional options.\n\t * @param {boolean} [options.prohibitParameters=false] The option to prohibit parameters when checking if the media type is JavaScript.\n\t * @returns {boolean} true if this instance represents a JavaScript media type, false otherwise.\n\t */\n\tisJavaScript({prohibitParameters = false} = {}) {\n\t\tswitch (this._type) {\n\t\t\tcase 'text': {\n\t\t\t\tswitch (this._subtype) {\n\t\t\t\t\tcase 'ecmascript':\n\t\t\t\t\tcase 'javascript':\n\t\t\t\t\tcase 'javascript1.0':\n\t\t\t\t\tcase 'javascript1.1':\n\t\t\t\t\tcase 'javascript1.2':\n\t\t\t\t\tcase 'javascript1.3':\n\t\t\t\t\tcase 'javascript1.4':\n\t\t\t\t\tcase 'javascript1.5':\n\t\t\t\t\tcase 'jscript':\n\t\t\t\t\tcase 'livescript':\n\t\t\t\t\tcase 'x-ecmascript':\n\t\t\t\t\tcase 'x-javascript': return !prohibitParameters || this._parameters.size === 0;\n\t\t\t\t\tdefault: return false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase 'application': {\n\t\t\t\tswitch (this._subtype) {\n\t\t\t\t\tcase 'ecmascript':\n\t\t\t\t\tcase 'javascript':\n\t\t\t\t\tcase 'x-ecmascript':\n\t\t\t\t\tcase 'x-javascript': return !prohibitParameters || this._parameters.size === 0;\n\t\t\t\t\tdefault: return false;\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefault: return false;\n\t\t}\n\t}\n\n\t/**\n\t * Determines if this instance is an XML media type.\n\t *\n\t * @returns {boolean} true if this instance represents an XML media type, false otherwise.\n\t */\n\tisXML() {\n\t\treturn (this._subtype === 'xml' && (this._type === 'text' || this._type === 'application')) || this._subtype.endsWith('+xml');\n\t}\n\n\t/**\n\t * Determines if this instance is an HTML media type.\n\t *\n\t * @returns {boolean} true if this instance represents an HTML media type, false otherwise.\n\t */\n\tisHTML() {\n\t\treturn this._subtype === 'html' && this._type === 'text';\n\t}\n\n\t/**\n\t * Gets the name of the class.\n\t *\n\t * @returns {string} The class name\n\t */\n\tget [Symbol.toStringTag]() {\n\t\treturn 'MediaType';\n\t}\n}", "/** @module utils */\n\n/**\n * A function to remove any leading and trailing HTTP whitespace.\n *\n * @param {string} string The string to process.\n * @returns {string} The processed string.\n */\nconst removeLeadingAndTrailingHTTPWhitespace = (string) => string.replace(/^[ \\t\\n\\r]+/u, '').replace(/[ \\t\\n\\r]+$/u, '');\n\n/**\n * A function to remove any trailing HTTP whitespace.\n *\n * @param {string} string The string to process.\n * @returns {string} The processed string.\n */\nconst removeTrailingHTTPWhitespace = (string) => string.replace(/[ \\t\\n\\r]+$/u, '');\n\n/**\n * Determines if the provided character is whitespace.\n *\n * @param {string} char The character to evaluate.\n * @returns {boolean} true if the character is whitespace, false otherwise.\n */\nconst isHTTPWhitespaceChar = (char) => char === ' ' || char === '\\t' || char === '\\n' || char === '\\r';\n\n/**\n * Determines if the provided string contains only HTTP token code points.\n *\n * @param {string} string The string to evaluate.\n * @returns {boolean} true if the string contains only HTTP token code points.\n */\nconst solelyContainsHTTPTokenCodePoints = (string) => /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u.test(string);\n\n/**\n * Determines if the provided string contains only quoted HTTP token code points.\n *\n * @param {string} string The string to evaluate.\n * @returns {boolean} true if the string contains only quoted HTTP token code points.\n */\nconst solelyContainsHTTPQuotedStringTokenCodePoints = (string) => /^[\\t\\u0020-\\u007E\\u0080-\\u00FF]*$/u.test(string);\n\n/**\n * A function to lower case ASCII characters.\n *\n * @param {string} string The string to process.\n * @returns {string} The processed string with all ASCII characters lower cased.\n */\nconst asciiLowercase = (string) => string.replace(/[A-Z]/ug, l => l.toLowerCase());\n\n/**\n * Collects all the HTTP quoted strings.\n * This variant only implements it with the extract-value flag set.\n *\n * @param {string} input The string to process.\n * @param {number} position The starting position.\n * @returns {Array<string | number>} An array that includes the resulting string and updated position.\n */\nconst collectAnHTTPQuotedString = (input, position) => {\n\tlet value = '';\n\n\tposition++;\n\n\twhile (true) {\n\t\twhile (position < input.length && input[position] !== '\"' && input[position] !== '\\\\') {\n\t\t\tvalue += input[position];\n\t\t\t++position;\n\t\t}\n\n\t\tif (position >= input.length) {\n\t\t\tbreak;\n\t\t}\n\n\t\tconst quoteOrBackslash = input[position];\n\t\t++position;\n\n\t\tif (quoteOrBackslash === '\\\\') {\n\t\t\tif (position >= input.length) {\n\t\t\t\tvalue += '\\\\';\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tvalue += input[position];\n\t\t\t++position;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn [value, position];\n};\n\nexport { removeLeadingAndTrailingHTTPWhitespace, removeTrailingHTTPWhitespace, isHTTPWhitespaceChar, solelyContainsHTTPTokenCodePoints, solelyContainsHTTPQuotedStringTokenCodePoints, asciiLowercase, collectAnHTTPQuotedString };\n", "import { asciiLowercase, solelyContainsHTTPQuotedStringTokenCodePoints, solelyContainsHTTPTokenCodePoints } from './utils.js';\n\n/**\n * Class representing the parameters for a MIME type record.\n * This class has the equivalent surface API to a JavaScript {@link Map}.\n *\n * However, {@link MediaTypeParameters} methods will always interpret their arguments\n * as appropriate for MIME types, so parameter names will be lowercased,\n * and attempting to set invalid characters will throw an {@link Error}.\n *\n * @example charset=utf-8\n * @module MediaTypeParameters\n */\nexport default class MediaTypeParameters {\n\t/**\n\t * Create a new MediaTypeParameters instance.\n\t *\n\t * @param {Map.<string, string>} map The map of parameters for a MIME type.\n\t */\n\tconstructor(map) {\n\t\tthis._map = map;\n\t}\n\n\t/**\n\t * Gets the number of MIME type parameters.\n\t *\n\t * @returns {number} The number of MIME type parameters\n\t */\n\tget size() {\n\t\treturn this._map.size;\n\t}\n\n\t/**\n\t * Gets the MIME type parameter value for the supplied name.\n\t *\n\t * @param {string} name The name of the MIME type parameter to retrieve.\n\t * @returns {string} The MIME type parameter value.\n\t */\n\tget(name) {\n\t\treturn this._map.get(asciiLowercase(String(name)));\n\t}\n\n\t/**\n\t * Indicates whether the MIME type parameter with the specified name exists or not.\n\t *\n\t * @param {string} name The name of the MIME type parameter to check.\n\t * @returns {boolean} true if the MIME type parameter exists, false otherwise.\n\t */\n\thas(name) {\n\t\treturn this._map.has(asciiLowercase(String(name)));\n\t}\n\n\t/**\n\t * Adds a new MIME type parameter using the specified name and value to the MediaTypeParameters.\n\t * If an parameter with the same name already exists, the parameter will be updated.\n\t *\n\t * @param {string} name The name of the MIME type parameter to set.\n\t * @param {string} value The MIME type parameter value.\n\t * @returns {MediaTypeParameters} This instance.\n\t */\n\tset(name, value) {\n\t\tname = asciiLowercase(String(name));\n\t\tvalue = String(value);\n\n\t\tif (!solelyContainsHTTPTokenCodePoints(name)) {\n\t\t\tthrow new Error(`Invalid MIME type parameter name \"${name}\": only HTTP token code points are valid.`);\n\t\t}\n\n\t\tif (!solelyContainsHTTPQuotedStringTokenCodePoints(value)) {\n\t\t\tthrow new Error(`Invalid MIME type parameter value \"${value}\": only HTTP quoted-string token code points are valid.`);\n\t\t}\n\n\t\tthis._map.set(name, value);\n\n\t\treturn this;\n\t}\n\n\t/**\n\t * Clears all the MIME type parameters.\n\t */\n\tclear() {\n\t\tthis._map.clear();\n\t}\n\n\t/**\n\t * Removes the MIME type parameter using the specified name.\n\t *\n\t * @param {string} name The name of the MIME type parameter to delete.\n\t * @returns {boolean} true if the parameter existed and has been removed, or false if the parameter does not exist.\n\t */\n\tdelete(name) {\n\t\tname = asciiLowercase(String(name));\n\t\treturn this._map.delete(name);\n\t}\n\n\t/**\n\t * Executes a provided function once per each name/value pair in the MediaTypeParameters, in insertion order.\n\t *\n\t * @param {function(string, string): void} callback The function called on each iteration.\n\t * @param {*} [thisArg] Optional object when binding 'this' to the callback.\n\t */\n\tforEach(callback, thisArg) {\n\t\tthis._map.forEach(callback, thisArg);\n\t}\n\n\t/**\n\t * Returns an iterable of parameter names.\n\t *\n\t * @returns {IterableIterator<string>} The {@link IterableIterator} of MIME type parameter names.\n\t */\n\tkeys() {\n\t\treturn this._map.keys();\n\t}\n\n\t/**\n\t * Returns an iterable of parameter values.\n\t *\n\t * @returns {IterableIterator<string>} The {@link IterableIterator} of MIME type parameter values.\n\t */\n\tvalues() {\n\t\treturn this._map.values();\n\t}\n\n\t/**\n\t * Returns an iterable of name, value pairs for every parameter entry in the MIME type parameters.\n\t *\n\t * @returns {IterableIterator<Array<Array<string>>>} The MIME type parameter entries.\n\t */\n\tentries() {\n\t\treturn this._map.entries();\n\t}\n\n\t/**\n\t * A method that returns the default iterator for the {@link MediaTypeParameters}. Called by the semantics of the for-of statement.\n\t *\n\t * @returns {Iterator<string, string, undefined>} The {@link Symbol.iterator} for the MIME type parameters.\n\t */\n\t[Symbol.iterator]() {\n\t\treturn this._map[Symbol.iterator]();\n\t}\n}", "import {\n\tasciiLowercase,\n\tcollectAnHTTPQuotedString, isHTTPWhitespaceChar, removeLeadingAndTrailingHTTPWhitespace,\n\tremoveTrailingHTTPWhitespace, solelyContainsHTTPQuotedStringTokenCodePoints, solelyContainsHTTPTokenCodePoints\n} from './utils.js';\n\n/**\n * Function to parse a media type.\n *\n * @module parser\n * @param {string} input The media type to parse\n * @returns {{ type: string, subtype: string, parameters: Map<string, string> }} An object populated with the parsed media type properties and any parameters.\n */\nconst parse = (input) => {\n\tinput = removeLeadingAndTrailingHTTPWhitespace(input);\n\n\tlet position = 0;\n\tlet type = '';\n\twhile (position < input.length && input[position] !== '/') {\n\t\ttype += input[position];\n\t\t++position;\n\t}\n\n\tif (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {\n\t\treturn null;\n\t}\n\n\tif (position >= input.length) {\n\t\treturn null;\n\t}\n\n\t// Skips past \"/\"\n\t++position;\n\n\tlet subtype = '';\n\twhile (position < input.length && input[position] !== ';') {\n\t\tsubtype += input[position];\n\t\t++position;\n\t}\n\n\tsubtype = removeTrailingHTTPWhitespace(subtype);\n\n\tif (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {\n\t\treturn null;\n\t}\n\n\tconst mediaType = {\n\t\ttype: asciiLowercase(type),\n\t\tsubtype: asciiLowercase(subtype),\n\t\tparameters: new Map()\n\t};\n\n\twhile (position < input.length) {\n\t\t// Skip past \";\"\n\t\t++position;\n\n\t\twhile (isHTTPWhitespaceChar(input[position])) {\n\t\t\t++position;\n\t\t}\n\n\t\tlet parameterName = '';\n\t\twhile (position < input.length && input[position] !== ';' && input[position] !== '=') {\n\t\t\tparameterName += input[position];\n\t\t\t++position;\n\t\t}\n\t\tparameterName = asciiLowercase(parameterName);\n\n\t\tif (position < input.length) {\n\t\t\tif (input[position] === ';') {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Skip past \"=\"\n\t\t\t++position;\n\t\t}\n\n\t\tlet parameterValue = null;\n\t\tif (input[position] === '\"') {\n\t\t\t[parameterValue, position] = collectAnHTTPQuotedString(input, position);\n\n\t\t\twhile (position < input.length && input[position] !== ';') {\n\t\t\t\t++position;\n\t\t\t}\n\t\t} else {\n\t\t\tparameterValue = '';\n\t\t\twhile (position < input.length && input[position] !== ';') {\n\t\t\t\tparameterValue += input[position];\n\t\t\t\t++position;\n\t\t\t}\n\n\t\t\tparameterValue = removeTrailingHTTPWhitespace(parameterValue);\n\n\t\t\tif (parameterValue === '') {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (parameterName.length > 0 &&\n\t\t\tsolelyContainsHTTPTokenCodePoints(parameterName) &&\n\t\t\tsolelyContainsHTTPQuotedStringTokenCodePoints(parameterValue) &&\n\t\t\t!mediaType.parameters.has(parameterName)) {\n\t\t\tmediaType.parameters.set(parameterName, parameterValue);\n\t\t}\n\t}\n\n\treturn mediaType;\n};\n\nexport default parse;", "import { solelyContainsHTTPTokenCodePoints } from './utils.js';\n// eslint-disable-next-line jsdoc/valid-types\n/** @typedef { import('./media-type.js').default } MediaType */\n\n/**\n * A function that serializes the provided {@link mediaType} to a string.\n *\n * @module serializer\n * @param {MediaType} mediaType The media type to serialize.\n * @returns {string} The serialized media type.\n */\nconst serialize = (mediaType) => {\n\tlet serialization = `${mediaType.type}/${mediaType.subtype}`;\n\n\tif (mediaType.parameters.size === 0) {\n\t\treturn serialization;\n\t}\n\n\tfor (let [name, value] of mediaType.parameters) {\n\t\tserialization += ';';\n\t\tserialization += name;\n\t\tserialization += '=';\n\n\t\tif (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {\n\t\t\tvalue = value.replace(/([\"\\\\])/ug, '\\\\$1');\n\t\t\tvalue = `\"${value}\"`;\n\t\t}\n\n\t\tserialization += value;\n\t}\n\n\treturn serialization;\n};\n\nexport default serialize;"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["media_type_exports", "__export", "MediaType", "removeLeadingAndTrailingHTTPWhitespace", "string", "removeTrailingHTTPWhitespace", "isHTTPWhitespaceChar", "char", "solelyContainsHTTPTokenCodePoints", "solelyContainsHTTPQuotedStringTokenCodePoints", "asciiLowercase", "l", "collectAnHTTPQuotedString", "input", "position", "value", "quoteOrBackslash", "MediaTypeParameters", "map", "name", "asciiLowercase", "value", "solelyContainsHTTPTokenCodePoints", "solelyContainsHTTPQuotedStringTokenCodePoints", "callback", "thisArg", "parse", "input", "removeLeadingAndTrailingHTTPWhitespace", "position", "type", "solelyContainsHTTPTokenCodePoints", "subtype", "removeTrailingHTTPWhitespace", "mediaType", "asciiLowercase", "isHTTPWhitespaceChar", "parameterName", "parameterValue", "collectAnHTTPQuotedString", "solelyContainsHTTPQuotedStringTokenCodePoints", "parser_default", "serialize", "mediaType", "serialization", "name", "value", "solelyContainsHTTPTokenCodePoints", "serializer_default", "MediaType", "string", "result", "parser_default", "MediaTypeParameters", "value", "asciiLowercase", "solelyContainsHTTPTokenCodePoints", "serializer_default", "prohibitParameters"]
|
|
7
|
+
}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as MediaTypeParameters } from "./src/media-type-parameters.js";
|
|
2
|
+
export { default as MediaType } from "./src/media-type.js";
|
|
3
|
+
export { default as parse } from "./src/parser.js";
|
|
4
|
+
export { default as serialize } from "./src/serializer.js";
|
|
5
|
+
export * from "./src/utils.js";
|
package/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as MediaTypeParameters } from './src/media-type-parameters.js';
|
|
2
|
+
export { default as MediaType } from './src/media-type.js';
|
|
3
|
+
export { default as parse } from './src/parser.js';
|
|
4
|
+
export { default as serialize } from './src/serializer.js';
|
|
5
|
+
export * from './src/utils.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@d1g1tal/media-type",
|
|
3
|
+
"description": "Parses, serializes, and manipulates media types, according to the WHATWG MIME Sniffing Standard",
|
|
4
|
+
"version": "4.0.0",
|
|
5
|
+
"author": "Domenic Denicola <d@domenic.me> (https://domenic.me/)",
|
|
6
|
+
"maintainers": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Jason DiMeo",
|
|
9
|
+
"email": "jason.dimeo@gmail.com"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/D1g1talEntr0py/media-type.git"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
21
|
+
"types": "./index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./index.js",
|
|
25
|
+
"default": "./dist/media-type.min.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"browser": {
|
|
29
|
+
"media-type.js": "./dist/media-type.js",
|
|
30
|
+
"media-type.min.js": "./dist/media-type.min.js",
|
|
31
|
+
"media-type.min.js.map": "./dist/media-type.min.js.map"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"index.js",
|
|
35
|
+
"index.d.ts",
|
|
36
|
+
"/src",
|
|
37
|
+
"/dist"
|
|
38
|
+
],
|
|
39
|
+
"keywords": [
|
|
40
|
+
"content-type",
|
|
41
|
+
"mime type",
|
|
42
|
+
"media type",
|
|
43
|
+
"mimesniff",
|
|
44
|
+
"http",
|
|
45
|
+
"whatwg"
|
|
46
|
+
],
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "rimraf dist && esbuild src/media-type.js --bundle --platform=browser --global-name=MediaType --footer:js='window.MediaType = MediaType.default;' --outfile=dist/media-type.js && esbuild src/media-type.js --bundle --sourcemap --minify --platform=browser --global-name=MediaType --footer:js='window.MediaType = MediaType.default;' --outfile=dist/media-type.min.js",
|
|
49
|
+
"test": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js",
|
|
50
|
+
"lint": "eslint --ext .js --fix --ignore-path .gitignore .",
|
|
51
|
+
"coverage": "node --no-warnings --experimental-vm-modules node_modules/jest/bin/jest.js --coverage",
|
|
52
|
+
"pretest": "node scripts/get-latest-platform-tests.js"
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"@skypack/package-check": "^0.2.2",
|
|
56
|
+
"esbuild": "^0.15.10",
|
|
57
|
+
"eslint": "^8.25.0",
|
|
58
|
+
"eslint-plugin-compat": "^4.0.2",
|
|
59
|
+
"eslint-plugin-jsdoc": "^39.3.6",
|
|
60
|
+
"jest": "^29.1.2",
|
|
61
|
+
"minipass-fetch": "^2.1.2",
|
|
62
|
+
"printable-string": "^0.3.0",
|
|
63
|
+
"rimraf": "^3.0.2",
|
|
64
|
+
"whatwg-encoding": "^2.0.0"
|
|
65
|
+
},
|
|
66
|
+
"browserslist": [
|
|
67
|
+
">= 0.5%",
|
|
68
|
+
"last 2 major versions",
|
|
69
|
+
"Firefox ESR",
|
|
70
|
+
"not dead",
|
|
71
|
+
"not ios_saf < 15",
|
|
72
|
+
"not op_mini all"
|
|
73
|
+
],
|
|
74
|
+
"engines": {
|
|
75
|
+
"node": ">=16"
|
|
76
|
+
},
|
|
77
|
+
"jest": {
|
|
78
|
+
"coverageDirectory": "coverage",
|
|
79
|
+
"coverageReporters": [
|
|
80
|
+
"lcov",
|
|
81
|
+
"text-summary"
|
|
82
|
+
],
|
|
83
|
+
"testEnvironment": "node",
|
|
84
|
+
"testMatch": [
|
|
85
|
+
"<rootDir>/test/**/*.js"
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|