@d1g1tal/media-type 4.1.0 → 5.0.1

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.
@@ -1,453 +1,299 @@
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
- });
1
+ // ../chrysalis/src/esm/object-type.js
2
+ var { toString } = Object.prototype;
3
+ var _type = (object) => object?.constructor ?? globalThis[toString.call(object).slice(8, -1)] ?? object;
4
+ var object_type_default = _type;
25
5
 
26
- // src/utils.js
27
- var whitespaceCharacters = [" ", " ", "\n", "\r"];
28
- var leadingWhitespace = /^[ \t\n\r]+/u;
29
- var trailingWhitespace = /[ \t\n\r]+$/u;
30
- var httpTokenCodePoints = /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u;
31
- var httpQuotedTokenCodePoints = /^[\t\u0020-\u007E\u0080-\u00FF]*$/u;
32
- var removeLeadingAndTrailingHTTPWhitespace = (string) => string.replace(leadingWhitespace, "").replace(trailingWhitespace, "");
33
- var removeTrailingHTTPWhitespace = (string) => string.replace(trailingWhitespace, "");
34
- var isHTTPWhitespaceChar = (char) => whitespaceCharacters.includes(char);
35
- var solelyContainsHTTPTokenCodePoints = (string) => httpTokenCodePoints.test(string);
36
- var solelyContainsHTTPQuotedStringTokenCodePoints = (string) => httpQuotedTokenCodePoints.test(string);
37
- var asciiLowercase = (string) => {
38
- let result = "";
39
- for (const [char, charCode = char.charCodeAt(0)] of string) {
40
- result += charCode >= 65 && charCode <= 90 ? String.fromCharCode(charCode + 32) : char;
41
- }
42
- return result;
43
- };
44
- var collectAnHTTPQuotedString = (input, position) => {
45
- let value = "";
46
- for (let length = input.length, char; ++position < length; ) {
47
- char = input[position];
48
- if (char == "\\") {
49
- value += ++position < length ? input[position] : char;
50
- } else if (char == '"') {
51
- break;
52
- } else {
53
- value += char;
54
- }
55
- }
56
- return [value, position];
57
- };
6
+ // src/utils.js
7
+ var httpTokenCodePoints = /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u;
8
+ var utils_default = httpTokenCodePoints;
58
9
 
59
- // src/media-type-parameters.js
60
- var MediaTypeParameters = class {
61
- /** @type {Map<string, string>} */
62
- #map;
63
- /**
64
- * Create a new MediaTypeParameters instance.
65
- *
66
- * @param {Array<Array<string>>} entries An array of [name, value] tuples.
67
- */
68
- constructor(entries) {
69
- this.#map = new Map(entries);
70
- }
71
- /**
72
- * Gets the number of media type parameters.
73
- *
74
- * @returns {number} The number of media type parameters
75
- */
76
- get size() {
77
- return this.#map.size;
78
- }
79
- /**
80
- * Gets the media type parameter value for the supplied name.
81
- *
82
- * @param {string} name The name of the media type parameter to retrieve.
83
- * @returns {string} The media type parameter value.
84
- */
85
- get(name) {
86
- return this.#map.get(asciiLowercase(String(name)));
87
- }
88
- /**
89
- * Indicates whether the media type parameter with the specified name exists or not.
90
- *
91
- * @param {string} name The name of the media type parameter to check.
92
- * @returns {boolean} true if the media type parameter exists, false otherwise.
93
- */
94
- has(name) {
95
- return this.#map.has(asciiLowercase(String(name)));
96
- }
97
- /**
98
- * Adds a new media type parameter using the specified name and value to the MediaTypeParameters.
99
- * If an parameter with the same name already exists, the parameter will be updated.
100
- *
101
- * @param {string} name The name of the media type parameter to set.
102
- * @param {string} value The media type parameter value.
103
- * @returns {MediaTypeParameters} This instance.
104
- */
105
- set(name, value) {
106
- name = asciiLowercase(String(name));
107
- value = String(value);
108
- if (!solelyContainsHTTPTokenCodePoints(name)) {
109
- throw new Error(`Invalid media type parameter name "${name}": only HTTP token code points are valid.`);
110
- }
111
- if (!solelyContainsHTTPQuotedStringTokenCodePoints(value)) {
112
- throw new Error(`Invalid media type parameter value "${value}": only HTTP quoted-string token code points are valid.`);
113
- }
114
- this.#map.set(name, value);
115
- return this;
116
- }
117
- /**
118
- * Clears all the media type parameters.
119
- */
120
- clear() {
121
- this.#map.clear();
122
- }
123
- /**
124
- * Removes the media type parameter using the specified name.
125
- *
126
- * @param {string} name The name of the media type parameter to delete.
127
- * @returns {boolean} true if the parameter existed and has been removed, or false if the parameter does not exist.
128
- */
129
- delete(name) {
130
- name = asciiLowercase(String(name));
131
- return this.#map.delete(name);
132
- }
133
- /**
134
- * Executes a provided function once per each name/value pair in the MediaTypeParameters, in insertion order.
135
- *
136
- * @param {function(string, string): void} callback The function called on each iteration.
137
- * @param {*} [thisArg] Optional object when binding 'this' to the callback.
138
- */
139
- forEach(callback, thisArg) {
140
- this.#map.forEach(callback, thisArg);
141
- }
142
- /**
143
- * Returns an iterable of parameter names.
144
- *
145
- * @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter names.
146
- */
147
- keys() {
148
- return this.#map.keys();
149
- }
150
- /**
151
- * Returns an iterable of parameter values.
152
- *
153
- * @returns {IterableIterator<string>} The {@link IterableIterator} of media type parameter values.
154
- */
155
- values() {
156
- return this.#map.values();
157
- }
158
- /**
159
- * Returns an iterable of name, value pairs for every parameter entry in the media type parameters.
160
- *
161
- * @returns {IterableIterator<Array<Array<string>>>} The media type parameter entries.
162
- */
163
- entries() {
164
- return this.#map.entries();
165
- }
166
- /**
167
- * A method that returns the default iterator for the {@link MediaTypeParameters}. Called by the semantics of the for-of statement.
168
- *
169
- * @returns {Iterator<string, string, undefined>} The {@link Symbol.iterator} for the media type parameters.
170
- */
171
- [Symbol.iterator]() {
172
- return this.#map[Symbol.iterator]();
173
- }
174
- /**
175
- * Returns a string representation of the media type parameters.
176
- * This method is called by the `String()` function.
177
- *
178
- * @example
179
- * const parameters = new MediaTypeParameters(new Map([['charset', 'utf-8']]));
180
- * String(parameters); // 'charset=utf-8'
181
- * parameters.toString(); // 'charset=utf-8'
182
- * parameters + ''; // 'charset=utf-8'
183
- * `${parameters}`; // 'charset=utf-8'
184
- * parameters[Symbol.toStringTag]; // 'MediaTypeParameters'
185
- * parameters[Symbol.toStringTag](); // 'MediaTypeParameters'
186
- * Object.prototype.toString.call(parameters); // '[object MediaTypeParameters]'
187
- * parameters + ''; // 'charset=utf-8'
188
- * @returns {string} The string representation of the media type parameters.
189
- */
190
- [Symbol.toStringTag]() {
191
- return "MediaTypeParameters";
192
- }
193
- };
10
+ // src/media-type-parameters.js
11
+ var matcher = /(["\\])/ug;
12
+ var httpQuotedStringTokenCodePoints = /^[\t\u0020-\u007E\u0080-\u00FF]*$/u;
13
+ var MediaTypeParameters = class _MediaTypeParameters extends Map {
14
+ /**
15
+ * Create a new MediaTypeParameters instance.
16
+ *
17
+ * @param {Array<[string, string]>} entries An array of [name, value] tuples.
18
+ */
19
+ constructor(entries = []) {
20
+ super(entries);
21
+ }
22
+ /**
23
+ * Indicates whether the supplied name and value are valid media type parameters.
24
+ *
25
+ * @static
26
+ * @param {string} name The name of the media type parameter to validate.
27
+ * @param {string} value The media type parameter value to validate.
28
+ * @returns {boolean} true if the media type parameter is valid, false otherwise.
29
+ */
30
+ static isValid(name, value) {
31
+ return utils_default.test(name) && httpQuotedStringTokenCodePoints.test(value);
32
+ }
33
+ /**
34
+ * Gets the media type parameter value for the supplied name.
35
+ *
36
+ * @param {string} name The name of the media type parameter to retrieve.
37
+ * @returns {string} The media type parameter value.
38
+ */
39
+ get(name) {
40
+ return super.get(name.toLowerCase());
41
+ }
42
+ /**
43
+ * Indicates whether the media type parameter with the specified name exists or not.
44
+ *
45
+ * @param {string} name The name of the media type parameter to check.
46
+ * @returns {boolean} true if the media type parameter exists, false otherwise.
47
+ */
48
+ has(name) {
49
+ return super.has(name.toLowerCase());
50
+ }
51
+ /**
52
+ * Adds a new media type parameter using the specified name and value to the MediaTypeParameters.
53
+ * If an parameter with the same name already exists, the parameter will be updated.
54
+ *
55
+ * @param {string} name The name of the media type parameter to set.
56
+ * @param {string} value The media type parameter value.
57
+ * @returns {MediaTypeParameters} This instance.
58
+ */
59
+ set(name, value) {
60
+ if (!_MediaTypeParameters.isValid(name, value)) {
61
+ throw new Error(`Invalid media type parameter name/value: ${name}/${value}`);
62
+ }
63
+ super.set(name.toLowerCase(), value);
64
+ return this;
65
+ }
66
+ /**
67
+ * Removes the media type parameter using the specified name.
68
+ *
69
+ * @param {string} name The name of the media type parameter to delete.
70
+ * @returns {boolean} true if the parameter existed and has been removed, or false if the parameter does not exist.
71
+ */
72
+ delete(name) {
73
+ return super.delete(name.toLowerCase());
74
+ }
75
+ /**
76
+ * Returns a string representation of the media type parameters.
77
+ *
78
+ * @override
79
+ * @returns {string} The string representation of the media type parameters.
80
+ */
81
+ toString() {
82
+ return Array.from(this).map(([name, value]) => `;${name}=${!value || !utils_default.test(value) ? `"${value.replace(matcher, "\\$1")}"` : value}`).join("");
83
+ }
84
+ /**
85
+ * Returns the name of this class.
86
+ *
87
+ * @override
88
+ * @returns {string} The name of this class.
89
+ */
90
+ [Symbol.toStringTag]() {
91
+ return "MediaTypeParameters";
92
+ }
93
+ };
194
94
 
195
- // src/parser.js
196
- var parse = (input) => {
197
- input = removeLeadingAndTrailingHTTPWhitespace(input);
198
- let position = 0;
199
- let type = "";
200
- while (position < input.length && input[position] != "/") {
201
- type += input[position];
202
- ++position;
203
- }
204
- if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
205
- return null;
206
- }
207
- if (position >= input.length) {
208
- return null;
209
- }
210
- ++position;
211
- let subtype = "";
212
- while (position < input.length && input[position] != ";") {
213
- subtype += input[position];
214
- ++position;
215
- }
216
- subtype = removeTrailingHTTPWhitespace(subtype);
217
- if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
218
- return null;
219
- }
220
- const mediaType = {
221
- type: asciiLowercase(type),
222
- subtype: asciiLowercase(subtype),
223
- parameters: /* @__PURE__ */ new Map()
224
- };
225
- while (position < input.length) {
226
- ++position;
227
- while (isHTTPWhitespaceChar(input[position])) {
95
+ // src/media-type-parser.js
96
+ var whitespaceCharacters = [" ", " ", "\n", "\r"];
97
+ var trailingWhitespace = /[ \t\n\r]+$/u;
98
+ var leadingAndTrailingWhitespace = /^[ \t\n\r]+|[ \t\n\r]+$/ug;
99
+ var MediaTypeParser = class _MediaTypeParser {
100
+ /**
101
+ * Function to parse a media type.
102
+ *
103
+ * @static
104
+ * @param {string} input The media type to parse
105
+ * @returns {{ type: string, subtype: string, parameters: MediaTypeParameters }} An object populated with the parsed media type properties and any parameters.
106
+ */
107
+ static parse(input) {
108
+ input = input.replace(leadingAndTrailingWhitespace, "");
109
+ const length = input.length, trim = true, lowerCase = false;
110
+ let { position, result: type, subtype = "" } = _MediaTypeParser.#filterComponent({ input }, "/");
111
+ if (!type.length || position >= length || !utils_default.test(type)) {
112
+ throw new TypeError(_MediaTypeParser.#generateErrorMessage("type", type));
113
+ }
114
+ ({ position, result: subtype } = _MediaTypeParser.#filterComponent({ position: ++position, input, trim }, ";"));
115
+ if (!subtype.length || !utils_default.test(subtype)) {
116
+ throw new TypeError(_MediaTypeParser.#generateErrorMessage("subtype", subtype));
117
+ }
118
+ let parameterName = "", parameterValue = null;
119
+ const parameters = new MediaTypeParameters();
120
+ while (position++ < length) {
121
+ while (whitespaceCharacters.includes(input[position])) {
228
122
  ++position;
229
123
  }
230
- let parameterName = "";
231
- while (position < input.length && input[position] != ";" && input[position] != "=") {
232
- parameterName += input[position];
233
- ++position;
234
- }
235
- parameterName = asciiLowercase(parameterName);
236
- if (position < input.length) {
124
+ ({ position, result: parameterName } = _MediaTypeParser.#filterComponent({ position, input, lowerCase }, ";", "="));
125
+ if (position < length) {
237
126
  if (input[position] == ";") {
238
127
  continue;
239
128
  }
240
129
  ++position;
241
130
  }
242
- let parameterValue = null;
243
131
  if (input[position] == '"') {
244
- [parameterValue, position] = collectAnHTTPQuotedString(input, position);
245
- while (position < input.length && input[position] != ";") {
132
+ [parameterValue, position] = _MediaTypeParser.#collectHttpQuotedString(input, position);
133
+ while (position < length && input[position] != ";") {
246
134
  ++position;
247
135
  }
248
136
  } else {
249
- parameterValue = "";
250
- while (position < input.length && input[position] != ";") {
251
- parameterValue += input[position];
252
- ++position;
253
- }
254
- parameterValue = removeTrailingHTTPWhitespace(parameterValue);
255
- if (parameterValue === "") {
137
+ ({ position, result: parameterValue } = _MediaTypeParser.#filterComponent({ position, input, lowerCase, trim }, ";"));
138
+ if (!parameterValue) {
256
139
  continue;
257
140
  }
258
141
  }
259
- if (parameterName.length > 0 && solelyContainsHTTPTokenCodePoints(parameterName) && solelyContainsHTTPQuotedStringTokenCodePoints(parameterValue) && !mediaType.parameters.has(parameterName)) {
260
- mediaType.parameters.set(parameterName, parameterValue);
142
+ if (parameterName && MediaTypeParameters.isValid(parameterName, parameterValue) && !parameters.has(parameterName)) {
143
+ parameters.set(parameterName, parameterValue);
261
144
  }
262
145
  }
263
- return mediaType;
264
- };
265
- var parser_default = parse;
266
-
267
- // src/serializer.js
268
- var serialize = (mediaType) => {
269
- let serialization = `${mediaType.type}/${mediaType.subtype}`;
270
- if (mediaType.parameters.size === 0) {
271
- return serialization;
272
- }
273
- for (let [name, value] of mediaType.parameters) {
274
- serialization += `;${name}=`;
275
- if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
276
- value = `"${value.replace(/(["\\])/ug, "\\$1")}"`;
146
+ return { type, subtype, parameters };
147
+ }
148
+ /**
149
+ * Filters a component from the input string.
150
+ *
151
+ * @private
152
+ * @static
153
+ * @param {Object} options The options.
154
+ * @param {number} [options.position] The starting position.
155
+ * @param {string} options.input The input string.
156
+ * @param {boolean} [options.lowerCase] Indicates whether the result should be lowercased.
157
+ * @param {boolean} [options.trim] Indicates whether the result should be trimmed.
158
+ * @param {string[]} charactersToFilter The characters to filter.
159
+ * @returns {{ position: number, result: string }} An object that includes the resulting string and updated position.
160
+ */
161
+ static #filterComponent({ position = 0, input, lowerCase = true, trim = false }, ...charactersToFilter) {
162
+ let result = "";
163
+ for (const length = input.length; position < length && !charactersToFilter.includes(input[position]); position++) {
164
+ result += input[position];
165
+ }
166
+ if (lowerCase) {
167
+ result = result.toLowerCase();
168
+ }
169
+ if (trim) {
170
+ result = result.replace(trailingWhitespace, "");
171
+ }
172
+ return { position, result };
173
+ }
174
+ /**
175
+ * Collects all the HTTP quoted strings.
176
+ * This variant only implements it with the extract-value flag set.
177
+ *
178
+ * @private
179
+ * @static
180
+ * @param {string} input The string to process.
181
+ * @param {number} position The starting position.
182
+ * @returns {Array<string|number>} An array that includes the resulting string and updated position.
183
+ */
184
+ static #collectHttpQuotedString(input, position) {
185
+ let value = "";
186
+ for (let length = input.length, char; ++position < length; ) {
187
+ if ((char = input[position]) == '"') {
188
+ break;
277
189
  }
278
- serialization += value;
190
+ value += char == "\\" && ++position < length ? input[position] : char;
279
191
  }
280
- return serialization;
281
- };
282
- var serializer_default = serialize;
192
+ return [value, position];
193
+ }
194
+ /**
195
+ * Generates an error message.
196
+ *
197
+ * @private
198
+ * @static
199
+ * @param {string} component The component name.
200
+ * @param {string} value The component value.
201
+ * @returns {string} The error message.
202
+ */
203
+ static #generateErrorMessage(component, value) {
204
+ return `Invalid ${component} "${value}": only HTTP token code points are valid.`;
205
+ }
206
+ };
283
207
 
284
- // src/media-type.js
285
- var MediaType = class {
286
- /** @type {string} */
287
- #type;
288
- /** @type {string} */
289
- #subtype;
290
- /** @type {MediaTypeParameters} */
291
- #parameters;
292
- /**
293
- * Create a new MediaType instance from a string representation.
294
- *
295
- * @param {string} mediaType The media type to parse.
296
- * @param {Object} [parameters] Optional parameters.
297
- */
298
- constructor(mediaType, parameters = {}) {
299
- const { type, subtype, parameters: parsedParameters } = parser_default(mediaType);
300
- this.#type = type;
301
- this.#subtype = subtype;
302
- this.#parameters = new MediaTypeParameters([...parsedParameters, ...Object.entries(parameters).map(([name, value]) => [asciiLowercase(name), asciiLowercase(value)])]);
303
- }
304
- /**
305
- * Static factory method for parsing a media type.
306
- *
307
- * @param {string} string The media type to parse.
308
- * @returns {MediaType} The parsed {@link MediaType} object or null if the string could not be parsed.
309
- */
310
- static parse(string) {
311
- try {
312
- return new MediaType(string);
313
- } catch (e) {
314
- throw new Error(`Could not parse media type string '${string}'`);
315
- }
316
- }
317
- /**
318
- * Gets the media type essence (type/subtype).
319
- *
320
- * @returns {string} The media type without any parameters
321
- */
322
- get essence() {
323
- return `${this.#type}/${this.#subtype}`;
324
- }
325
- /**
326
- * Gets the type.
327
- *
328
- * @returns {string} The type.
329
- */
330
- get type() {
331
- return this.#type;
332
- }
333
- /**
334
- * Sets the type.
335
- */
336
- set type(value) {
337
- value = asciiLowercase(String(value));
338
- if (value.length === 0) {
339
- throw new Error("Invalid type: must be a non-empty string");
340
- }
341
- if (!solelyContainsHTTPTokenCodePoints(value)) {
342
- throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
343
- }
344
- this.#type = value;
345
- }
346
- /**
347
- * Gets the subtype.
348
- *
349
- * @returns {string} The subtype.
350
- */
351
- get subtype() {
352
- return this.#subtype;
353
- }
354
- /**
355
- * Sets the subtype.
356
- */
357
- set subtype(value) {
358
- value = asciiLowercase(String(value));
359
- if (value.length === 0) {
360
- throw new Error("Invalid subtype: must be a non-empty string");
361
- }
362
- if (!solelyContainsHTTPTokenCodePoints(value)) {
363
- throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
364
- }
365
- this.#subtype = value;
366
- }
367
- /**
368
- * Gets the parameters.
369
- *
370
- * @returns {MediaTypeParameters} The media type parameters.
371
- */
372
- get parameters() {
373
- return this.#parameters;
374
- }
375
- /**
376
- * Gets the serialized version of the media type.
377
- *
378
- * @returns {string} The serialized media type.
379
- */
380
- toString() {
381
- return serializer_default(this);
382
- }
383
- /**
384
- * Determines if this instance is a JavaScript media type.
385
- *
386
- * @param {Object} [options] Optional options.
387
- * @param {boolean} [options.prohibitParameters=false] The option to prohibit parameters when checking if the media type is JavaScript.
388
- * @returns {boolean} true if this instance represents a JavaScript media type, false otherwise.
389
- */
390
- isJavaScript({ prohibitParameters = false } = {}) {
391
- switch (this.#type) {
392
- case "text": {
393
- switch (this.#subtype) {
394
- case "ecmascript":
395
- case "javascript":
396
- case "javascript1.0":
397
- case "javascript1.1":
398
- case "javascript1.2":
399
- case "javascript1.3":
400
- case "javascript1.4":
401
- case "javascript1.5":
402
- case "jscript":
403
- case "livescript":
404
- case "x-ecmascript":
405
- case "x-javascript":
406
- return !prohibitParameters || this.#parameters.size === 0;
407
- default:
408
- return false;
409
- }
410
- }
411
- case "application": {
412
- switch (this.#subtype) {
413
- case "ecmascript":
414
- case "javascript":
415
- case "x-ecmascript":
416
- case "x-javascript":
417
- return !prohibitParameters || this.#parameters.size === 0;
418
- default:
419
- return false;
420
- }
421
- }
422
- default:
423
- return false;
424
- }
425
- }
426
- /**
427
- * Determines if this instance is an XML media type.
428
- *
429
- * @returns {boolean} true if this instance represents an XML media type, false otherwise.
430
- */
431
- isXML() {
432
- return this.#subtype === "xml" && (this.#type === "text" || this.#type === "application") || this.#subtype.endsWith("+xml");
433
- }
434
- /**
435
- * Determines if this instance is an HTML media type.
436
- *
437
- * @returns {boolean} true if this instance represents an HTML media type, false otherwise.
438
- */
439
- isHTML() {
440
- return this.#subtype === "html" && this.#type === "text";
441
- }
442
- /**
443
- * Gets the name of the class.
444
- *
445
- * @returns {string} The class name
446
- */
447
- get [Symbol.toStringTag]() {
448
- return "MediaType";
449
- }
450
- };
451
- return __toCommonJS(media_type_exports);
452
- })();
453
- window.MediaType = MediaType.default;
208
+ // src/media-type.js
209
+ var MediaType = class _MediaType {
210
+ /** @type {string} */
211
+ #type;
212
+ /** @type {string} */
213
+ #subtype;
214
+ /** @type {MediaTypeParameters} */
215
+ #parameters;
216
+ /**
217
+ * Create a new MediaType instance from a string representation.
218
+ *
219
+ * @param {string} mediaType The media type to parse.
220
+ * @param {Object} [parameters] Optional parameters.
221
+ */
222
+ constructor(mediaType, parameters = {}) {
223
+ if (object_type_default(parameters) != Object) {
224
+ throw new TypeError("The parameters argument must be an object");
225
+ }
226
+ ({ type: this.#type, subtype: this.#subtype, parameters: this.#parameters } = MediaTypeParser.parse(mediaType));
227
+ for (const [name, value] of Object.entries(parameters)) {
228
+ this.#parameters.set(name, value);
229
+ }
230
+ }
231
+ static parse(mediaType) {
232
+ try {
233
+ return new _MediaType(mediaType);
234
+ } catch (e) {
235
+ }
236
+ return null;
237
+ }
238
+ /**
239
+ * Gets the type.
240
+ *
241
+ * @returns {string} The type.
242
+ */
243
+ get type() {
244
+ return this.#type;
245
+ }
246
+ /**
247
+ * Gets the subtype.
248
+ *
249
+ * @returns {string} The subtype.
250
+ */
251
+ get subtype() {
252
+ return this.#subtype;
253
+ }
254
+ /**
255
+ * Gets the media type essence (type/subtype).
256
+ *
257
+ * @returns {string} The media type without any parameters
258
+ */
259
+ get essence() {
260
+ return `${this.#type}/${this.#subtype}`;
261
+ }
262
+ /**
263
+ * Gets the parameters.
264
+ *
265
+ * @returns {MediaTypeParameters} The media type parameters.
266
+ */
267
+ get parameters() {
268
+ return this.#parameters;
269
+ }
270
+ /**
271
+ * Checks if the media type matches the specified type.
272
+ *
273
+ * @todo Fix string handling to parse the type and subtype from the string.
274
+ * @param {MediaType|string} mediaType The media type to check.
275
+ * @returns {boolean} true if the media type matches the specified type, false otherwise.
276
+ */
277
+ matches(mediaType) {
278
+ return this.#type === mediaType?.type && this.#subtype === mediaType?.subtype || this.essence.includes(mediaType);
279
+ }
280
+ /**
281
+ * Gets the serialized version of the media type.
282
+ *
283
+ * @returns {string} The serialized media type.
284
+ */
285
+ toString() {
286
+ return `${this.essence}${this.#parameters.toString()}`;
287
+ }
288
+ /**
289
+ * Gets the name of the class.
290
+ *
291
+ * @returns {string} The class name
292
+ */
293
+ get [Symbol.toStringTag]() {
294
+ return "MediaType";
295
+ }
296
+ };
297
+ export {
298
+ MediaType as default
299
+ };