Skip to content

Commit 717b604

Browse files
bmeckTrottaduh95
authored andcommitted
util: add MIME utilities (#21128)
Co-authored-by: Rich Trott <rtrott@gmail.com> Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> PR-URL: #21128 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Robert Nagy <ronagy@icloud.com> Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent b5811c4 commit 717b604

16 files changed

+5123
-17
lines changed

doc/api/errors.md

+6
Original file line numberDiff line numberDiff line change
@@ -1967,6 +1967,12 @@ An invalid HTTP token was supplied.
19671967

19681968
An IP address is not valid.
19691969

1970+
<a id="ERR_INVALID_MIME_SYNTAX"></a>
1971+
1972+
### `ERR_INVALID_MIME_SYNTAX`
1973+
1974+
The syntax of a MIME is not valid.
1975+
19701976
<a id="ERR_INVALID_MODULE"></a>
19711977

19721978
### `ERR_INVALID_MODULE`

doc/api/util.md

+353
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,355 @@ Otherwise, returns `false`.
10201020
See [`assert.deepStrictEqual()`][] for more information about deep strict
10211021
equality.
10221022

1023+
## Class: `util.MIMEType`
1024+
1025+
<!-- YAML
1026+
added: REPLACEME
1027+
-->
1028+
1029+
> Stability: 1 - Experimental
1030+
1031+
An implementation of [the MIMEType class](https://bmeck.github.io/node-proposal-mime-api/).
1032+
1033+
In accordance with browser conventions, all properties of `MIMEType` objects
1034+
are implemented as getters and setters on the class prototype, rather than as
1035+
data properties on the object itself.
1036+
1037+
A MIME string is a structured string containing multiple meaningful
1038+
components. When parsed, a `MIMEType` object is returned containing
1039+
properties for each of these components.
1040+
1041+
### Constructor: `new MIMEType(input)`
1042+
1043+
* `input` {string} The input MIME to parse
1044+
1045+
Creates a new `MIMEType` object by parsing the `input`.
1046+
1047+
```mjs
1048+
import { MIMEType } from 'node:util';
1049+
1050+
const myMIME = new MIMEType('text/plain');
1051+
```
1052+
1053+
```cjs
1054+
const { MIMEType } = require('node:util');
1055+
1056+
const myMIME = new MIMEType('text/plain');
1057+
```
1058+
1059+
A `TypeError` will be thrown if the `input` is not a valid MIME. Note
1060+
that an effort will be made to coerce the given values into strings. For
1061+
instance:
1062+
1063+
```mjs
1064+
import { MIMEType } from 'node:util';
1065+
const myMIME = new MIMEType({ toString: () => 'text/plain' });
1066+
console.log(String(myMIME));
1067+
// Prints: text/plain
1068+
```
1069+
1070+
```cjs
1071+
const { MIMEType } = require('node:util');
1072+
const myMIME = new MIMEType({ toString: () => 'text/plain' });
1073+
console.log(String(myMIME));
1074+
// Prints: text/plain
1075+
```
1076+
1077+
#### `mime.type`
1078+
1079+
* {string}
1080+
1081+
Gets and sets the type portion of the MIME.
1082+
1083+
```mjs
1084+
import { MIMEType } from 'node:util';
1085+
1086+
const myMIME = new MIMEType('text/javascript');
1087+
console.log(myMIME.type);
1088+
// Prints: text
1089+
myMIME.type = 'application';
1090+
console.log(myMIME.type);
1091+
// Prints: application
1092+
console.log(String(myMIME));
1093+
// Prints: application/javascript
1094+
```
1095+
1096+
```cjs
1097+
const { MIMEType } = require('node:util');
1098+
1099+
const myMIME = new MIMEType('text/javascript');
1100+
console.log(myMIME.type);
1101+
// Prints: text
1102+
myMIME.type = 'application';
1103+
console.log(myMIME.type);
1104+
// Prints: application
1105+
console.log(String(myMIME));
1106+
// Prints: application/javascript/javascript
1107+
```
1108+
1109+
#### `mime.subtype`
1110+
1111+
* {string}
1112+
1113+
Gets and sets the subtype portion of the MIME.
1114+
1115+
```mjs
1116+
import { MIMEType } from 'node:util';
1117+
1118+
const myMIME = new MIMEType('text/ecmascript');
1119+
console.log(myMIME.subtype);
1120+
// Prints: ecmascript
1121+
myMIME.subtype = 'javascript';
1122+
console.log(myMIME.subtype);
1123+
// Prints: javascript
1124+
console.log(String(myMIME));
1125+
// Prints: text/javascript
1126+
```
1127+
1128+
```cjs
1129+
const { MIMEType } = require('node:util');
1130+
1131+
const myMIME = new MIMEType('text/ecmascript');
1132+
console.log(myMIME.subtype);
1133+
// Prints: ecmascript
1134+
myMIME.subtype = 'javascript';
1135+
console.log(myMIME.subtype);
1136+
// Prints: javascript
1137+
console.log(String(myMIME));
1138+
// Prints: text/javascript
1139+
```
1140+
1141+
#### `mime.essence`
1142+
1143+
* {string}
1144+
1145+
Gets the essence of the MIME. This property is read only.
1146+
Use `mime.type` or `mime.subtype` to alter the MIME.
1147+
1148+
```mjs
1149+
import { MIMEType } from 'node:util';
1150+
1151+
const myMIME = new MIMEType('text/javascript;key=value');
1152+
console.log(myMIME.essence);
1153+
// Prints: text/javascript
1154+
myMIME.type = 'application';
1155+
console.log(myMIME.essence);
1156+
// Prints: application/javascript
1157+
console.log(String(myMIME));
1158+
// Prints: application/javascript;key=value
1159+
```
1160+
1161+
```cjs
1162+
const { MIMEType } = require('node:util');
1163+
1164+
const myMIME = new MIMEType('text/javascript;key=value');
1165+
console.log(myMIME.essence);
1166+
// Prints: text/javascript
1167+
myMIME.type = 'application';
1168+
console.log(myMIME.essence);
1169+
// Prints: application/javascript
1170+
console.log(String(myMIME));
1171+
// Prints: application/javascript;key=value
1172+
```
1173+
1174+
#### `mime.params`
1175+
1176+
* {MIMEParams}
1177+
1178+
Gets the [`MIMEParams`][] object representing the
1179+
parameters of the MIME. This property is read-only. See
1180+
[`MIMEParams`][] documentation for details.
1181+
1182+
#### `mime.toString()`
1183+
1184+
* Returns: {string}
1185+
1186+
The `toString()` method on the `MIMEType` object returns the serialized MIME.
1187+
1188+
Because of the need for standard compliance, this method does not allow users
1189+
to customize the serialization process of the MIME.
1190+
1191+
#### `mime.toJSON()`
1192+
1193+
* Returns: {string}
1194+
1195+
Alias for [`mime.toString()`][].
1196+
1197+
This method is automatically called when an `MIMEType` object is serialized
1198+
with [`JSON.stringify()`][].
1199+
1200+
```mjs
1201+
import { MIMEType } from 'node:util';
1202+
1203+
const myMIMES = [
1204+
new MIMEType('image/png'),
1205+
new MIMEType('image/gif'),
1206+
];
1207+
console.log(JSON.stringify(myMIMES));
1208+
// Prints: ["image/png", "image/gif"]
1209+
```
1210+
1211+
```cjs
1212+
const { MIMEType } = require('node:util');
1213+
1214+
const myMIMES = [
1215+
new MIMEType('image/png'),
1216+
new MIMEType('image/gif'),
1217+
];
1218+
console.log(JSON.stringify(myMIMES));
1219+
// Prints: ["image/png", "image/gif"]
1220+
```
1221+
1222+
### Class: `util.MIMEParams`
1223+
1224+
<!-- YAML
1225+
added: REPLACEME
1226+
-->
1227+
1228+
The `MIMEParams` API provides read and write access to the parameters of a
1229+
`MIMEType`.
1230+
1231+
#### Constructor: `new MIMEParams()`
1232+
1233+
Creates a new `MIMEParams` object by with empty parameters
1234+
1235+
```mjs
1236+
import { MIMEParams } from 'node:util';
1237+
1238+
const myParams = new MIMEParams();
1239+
```
1240+
1241+
```cjs
1242+
const { MIMEParams } = require('node:util');
1243+
1244+
const myParams = new MIMEParams();
1245+
```
1246+
1247+
#### `mimeParams.delete(name)`
1248+
1249+
* `name` {string}
1250+
1251+
Remove all name-value pairs whose name is `name`.
1252+
1253+
#### `mimeParams.entries()`
1254+
1255+
* Returns: {Iterator}
1256+
1257+
Returns an iterator over each of the name-value pairs in the parameters.
1258+
Each item of the iterator is a JavaScript `Array`. The first item of the array
1259+
is the `name`, the second item of the array is the `value`.
1260+
1261+
#### `mimeParams.get(name)`
1262+
1263+
* `name` {string}
1264+
* Returns: {string} or `null` if there is no name-value pair with the given
1265+
`name`.
1266+
1267+
Returns the value of the first name-value pair whose name is `name`. If there
1268+
are no such pairs, `null` is returned.
1269+
1270+
#### `mimeParams.has(name)`
1271+
1272+
* `name` {string}
1273+
* Returns: {boolean}
1274+
1275+
Returns `true` if there is at least one name-value pair whose name is `name`.
1276+
1277+
#### `mimeParams.keys()`
1278+
1279+
* Returns: {Iterator}
1280+
1281+
Returns an iterator over the names of each name-value pair.
1282+
1283+
```mjs
1284+
import { MIMEType } from 'node:util';
1285+
1286+
const { params } = new MIMEType('text/plain;foo=0;bar=1');
1287+
for (const name of params.keys()) {
1288+
console.log(name);
1289+
}
1290+
// Prints:
1291+
// foo
1292+
// bar
1293+
```
1294+
1295+
```cjs
1296+
const { MIMEType } = require('node:util');
1297+
1298+
const { params } = new MIMEType('text/plain;foo=0;bar=1');
1299+
for (const name of params.keys()) {
1300+
console.log(name);
1301+
}
1302+
// Prints:
1303+
// foo
1304+
// bar
1305+
```
1306+
1307+
#### `mimeParams.set(name, value)`
1308+
1309+
* `name` {string}
1310+
* `value` {string}
1311+
1312+
Sets the value in the `MIMEParams` object associated with `name` to
1313+
`value`. If there are any pre-existing name-value pairs whose names are `name`,
1314+
set the first such pair's value to `value`.
1315+
1316+
```mjs
1317+
import { MIMEType } from 'node:util';
1318+
1319+
const { params } = new MIMEType('text/plain;foo=0;bar=1');
1320+
params.set('foo', 'def');
1321+
params.set('baz', 'xyz');
1322+
console.log(params.toString());
1323+
// Prints: foo=def&bar=1&baz=xyz
1324+
```
1325+
1326+
```cjs
1327+
const { MIMEType } = require('node:util');
1328+
1329+
const { params } = new MIMEType('text/plain;foo=0;bar=1');
1330+
params.set('foo', 'def');
1331+
params.set('baz', 'xyz');
1332+
console.log(params.toString());
1333+
// Prints: foo=def&bar=1&baz=xyz
1334+
```
1335+
1336+
#### `mimeParams.values()`
1337+
1338+
* Returns: {Iterator}
1339+
1340+
Returns an iterator over the values of each name-value pair.
1341+
1342+
#### `mimeParams[@@iterator]()`
1343+
1344+
* Returns: {Iterator}
1345+
1346+
Alias for [`mimeParams.entries()`][].
1347+
1348+
```mjs
1349+
import { MIMEType } from 'node:util';
1350+
1351+
const { params } = new MIMEType('text/plain;foo=bar;xyz=baz');
1352+
for (const [name, value] of params) {
1353+
console.log(name, value);
1354+
}
1355+
// Prints:
1356+
// foo bar
1357+
// xyz baz
1358+
```
1359+
1360+
```cjs
1361+
const { MIMEType } = require('node:util');
1362+
1363+
const { params } = new MIMEType('text/plain;foo=bar;xyz=baz');
1364+
for (const [name, value] of params) {
1365+
console.log(name, value);
1366+
}
1367+
// Prints:
1368+
// foo bar
1369+
// xyz baz
1370+
```
1371+
10231372
## `util.parseArgs([config])`
10241373

10251374
<!-- YAML
@@ -2897,6 +3246,8 @@ util.log('Timestamped message.');
28973246
[`Int16Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array
28983247
[`Int32Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array
28993248
[`Int8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array
3249+
[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
3250+
[`MIMEparams`]: #class-utilmimeparams
29003251
[`Map`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
29013252
[`Object.assign()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
29023253
[`Object.freeze()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
@@ -2914,6 +3265,8 @@ util.log('Timestamped message.');
29143265
[`WebAssembly.Module`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
29153266
[`assert.deepStrictEqual()`]: assert.md#assertdeepstrictequalactual-expected-message
29163267
[`console.error()`]: console.md#consoleerrordata-args
3268+
[`mime.toString()`]: #mimetostring
3269+
[`mimeParams.entries()`]: #mimeparamsentries
29173270
[`napi_create_external()`]: n-api.md#napi_create_external
29183271
[`target` and `handler`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#Terminology
29193272
[`tty.hasColors()`]: tty.md#writestreamhascolorscount-env

0 commit comments

Comments
 (0)