aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/whatwg-mimetype
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-14 14:46:37 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-14 14:46:37 -0800
commitafa87af01c79a9baa539f2992d32154d2a4739bd (patch)
tree92c7416db734270a2fee1d72ee9cc119379ff8e1 /vanilla/node_modules/whatwg-mimetype
parent3b927e84d200402281f68181cd4253bc77e5528d (diff)
downloadneko-afa87af01c79a9baa539f2992d32154d2a4739bd.tar.gz
neko-afa87af01c79a9baa539f2992d32154d2a4739bd.tar.bz2
neko-afa87af01c79a9baa539f2992d32154d2a4739bd.zip
task: delete vanilla js prototype\n\n- Removed vanilla/ directory and web/dist/vanilla directory\n- Updated Makefile, Dockerfile, and CI workflow to remove vanilla references\n- Cleaned up web/web.go to remove vanilla embed and routes\n- Verified build and tests pass\n\nCloses NK-2tcnmq
Diffstat (limited to 'vanilla/node_modules/whatwg-mimetype')
-rw-r--r--vanilla/node_modules/whatwg-mimetype/LICENSE.txt7
-rw-r--r--vanilla/node_modules/whatwg-mimetype/README.md132
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/index.js4
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/mime-type-parameters.js70
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/mime-type.js127
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/parser.js105
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/serializer.js25
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/sniff.js751
-rw-r--r--vanilla/node_modules/whatwg-mimetype/lib/utils.js60
-rw-r--r--vanilla/node_modules/whatwg-mimetype/package.json44
10 files changed, 0 insertions, 1325 deletions
diff --git a/vanilla/node_modules/whatwg-mimetype/LICENSE.txt b/vanilla/node_modules/whatwg-mimetype/LICENSE.txt
deleted file mode 100644
index 4220dea..0000000
--- a/vanilla/node_modules/whatwg-mimetype/LICENSE.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright © Domenic Denicola <d@domenic.me>
-
-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:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-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.
diff --git a/vanilla/node_modules/whatwg-mimetype/README.md b/vanilla/node_modules/whatwg-mimetype/README.md
deleted file mode 100644
index 40d7310..0000000
--- a/vanilla/node_modules/whatwg-mimetype/README.md
+++ /dev/null
@@ -1,132 +0,0 @@
-# Parse, serialize, manipulate, and sniff MIME types
-
-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:
-
-```js
-const { MIMEType } = require("whatwg-mimetype");
-
-const mimeType = new MIMEType(`Text/HTML;Charset="utf-8"`);
-
-console.assert(mimeType.toString() === "text/html;charset=utf-8");
-
-console.assert(mimeType.type === "text");
-console.assert(mimeType.subtype === "html");
-console.assert(mimeType.essence === "text/html");
-console.assert(mimeType.parameters.get("charset") === "utf-8");
-
-mimeType.parameters.set("charset", "windows-1252");
-console.assert(mimeType.parameters.get("charset") === "windows-1252");
-console.assert(mimeType.toString() === "text/html;charset=windows-1252");
-
-console.assert(mimeType.isHTML() === true);
-console.assert(mimeType.isXML() === false);
-```
-
-It can also [determine the MIME type of a resource](https://mimesniff.spec.whatwg.org/#determining-the-computed-mime-type-of-a-resource) by sniffing its contents:
-
-```js
-const { computedMIMEType } = require("whatwg-mimetype");
-
-const pngBytes = new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
-
-computedMIMEType(pngBytes).essence; // "image/png"
-computedMIMEType(pngBytes, { contentTypeHeader: "image/gif" }).essence // "image/png"
-computedMIMEType(pngBytes, { contentTypeHeader: "text/html" }).essence // "text/html"
-```
-
-Parsing, serialization, and sniffing are all fairly complex processes; see the specification for more details:
-
-* [parsing](https://mimesniff.spec.whatwg.org/#parsing-a-mime-type)
-* [serialization](https://mimesniff.spec.whatwg.org/#serializing-a-mime-type)
-* [sniffing](https://mimesniff.spec.whatwg.org/#determining-the-computed-mime-type-of-a-resource)
-
-This package's algorithms conform to those of the WHATWG [MIME Sniffing Standard](https://mimesniff.spec.whatwg.org/), as of [commit `e7594d5`](https://github.com/whatwg/mimesniff/commit/e7594d531819053508447f688a3bde465531aca5).
-
-## APIs
-
-### `MIMEType`
-
-The `MIMEType` class's constructor takes a string which it will attempt to parse into a MIME type; if parsing fails, an `Error` will be thrown.
-
-#### The `parse()` static factory method
-
-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.
-
-#### Properties
-
-* `type`: the MIME type's [type](https://mimesniff.spec.whatwg.org/#mime-type-type), e.g. `"text"`
-* `subtype`: the MIME type's [subtype](https://mimesniff.spec.whatwg.org/#mime-type-subtype), e.g. `"html"`
-* `essence`: the MIME type's [essence](https://mimesniff.spec.whatwg.org/#mime-type-essence), e.g. `"text/html"`
-* `parameters`: an instance of `MIMETypeParameters`, containing this MIME type's [parameters](https://mimesniff.spec.whatwg.org/#mime-type-parameters)
-
-`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).
-
-`essence` is only a getter, and cannot be changed.
-
-`parameters` is also a getter, but the contents of the `MIMETypeParameters` object are mutable, as described below.
-
-#### Methods
-
-* `toString()` serializes the MIME type to a string
-* `isHTML()`: returns true if this instance represents [a HTML MIME type](https://mimesniff.spec.whatwg.org/#html-mime-type)
-* `isXML()`: returns true if this instance represents [an XML MIME type](https://mimesniff.spec.whatwg.org/#xml-mime-type)
-* `isJavaScript({ prohibitParameters })`: returns true if this instance represents [a JavaScript MIME 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 MIME type's serialization is a [JavaScript MIME type essence match](https://mimesniff.spec.whatwg.org/#javascript-mime-type-essence-match).
-
-_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._
-
-### `MIMETypeParameters`
-
-The `MIMETypeParameters` class, instances of which are returned by `mimeType.parameters`, has equivalent surface API to a [JavaScript `Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map).
-
-However, `MIMETypeParameters` methods will always interpret their arguments as appropriate for MIME types, so e.g. parameter names will be lowercased, and attempting to set invalid characters will throw.
-
-Some examples:
-
-```js
-const { MIMEType } = require("whatwg-mimetype");
-
-const mimeType = new MIMEType(`x/x;a=b;c=D;E="F"`);
-
-// Logs:
-// a b
-// c D
-// e F
-for (const [name, value] of mimeType.parameters) {
- console.log(name, value);
-}
-
-console.assert(mimeType.parameters.has("a"));
-console.assert(mimeType.parameters.has("A"));
-console.assert(mimeType.parameters.get("A") === "b");
-
-mimeType.parameters.set("Q", "X");
-console.assert(mimeType.parameters.get("q") === "X");
-console.assert(mimeType.toString() === "x/x;a=b;c=d;e=F;q=X");
-
-// Throws:
-mimeType.parameters.set("@", "x");
-```
-
-### `computedMIMEType()`
-
-The `computedMIMEType(resource, options)` function determines a resource's MIME type using the full [MIME type sniffing algorithm](https://mimesniff.spec.whatwg.org/#determining-the-computed-mime-type-of-a-resource). This includes:
-
-* complexities around how the supplied `Content-Type` header or other external information interacts with (but usually does not override) the sniffing process;
-* the ability to set a "no-sniff" flag, like the one used when `X-Content-Type-Options: nosniff` is present, which mostly (but not entirely) prevents sniffing; and
-* the "Apache bug" check which occurs when the `Content-Type` header is one of several specific values.
-
-That is, this doesn't just implement the [rules for identifying an unknown MIME type](https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type). It gives you everything you need for a full browser-compatible MIME sniffing procedure.
-
-#### Arguments
-
-* **`resource`** (`Uint8Array`): The resource bytes.
-* **`options.contentTypeHeader`** (`string`): The Content-Type header value, for HTTP resources.
-* **`options.providedType`** (`string`): The MIME type from the filesystem or another protocol (like FTP), for non-HTTP resources.
-* **`options.noSniff`** (`boolean`, default `false`): Whether the `X-Content-Type-Options: nosniff` header was present.
-* **`options.isSupported`** (`function`, default `() => true`): A predicate called with a `MIMEType` instance to check if an image/audio/video MIME type is supported by the user agent. If it returns `false`, sniffing is skipped for that type.
-
-The `contentTypeHeader` and `providedType` options will be stringified, so you could also supply a `MIMEType` (or a [Node.js `util` module `MIMEType`](https://nodejs.org/api/util.html#class-utilmimetype)).
-
-#### Return value
-
-A `MIMEType` instance representing the computed MIME type.
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/index.js b/vanilla/node_modules/whatwg-mimetype/lib/index.js
deleted file mode 100644
index d21b3b1..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/index.js
+++ /dev/null
@@ -1,4 +0,0 @@
-"use strict";
-
-exports.MIMEType = require("./mime-type.js");
-exports.computedMIMEType = require("./sniff.js");
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/mime-type-parameters.js b/vanilla/node_modules/whatwg-mimetype/lib/mime-type-parameters.js
deleted file mode 100644
index ea4b2f0..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/mime-type-parameters.js
+++ /dev/null
@@ -1,70 +0,0 @@
-"use strict";
-const {
- asciiLowercase,
- solelyContainsHTTPTokenCodePoints,
- soleyContainsHTTPQuotedStringTokenCodePoints
-} = require("./utils.js");
-
-module.exports = class MIMETypeParameters {
- constructor(map) {
- this._map = map;
- }
-
- get size() {
- return this._map.size;
- }
-
- get(name) {
- name = asciiLowercase(String(name));
- return this._map.get(name);
- }
-
- has(name) {
- name = asciiLowercase(String(name));
- return this._map.has(name);
- }
-
- set(name, value) {
- name = asciiLowercase(String(name));
- value = String(value);
-
- if (!solelyContainsHTTPTokenCodePoints(name)) {
- throw new Error(`Invalid MIME type parameter name "${name}": only HTTP token code points are valid.`);
- }
- if (!soleyContainsHTTPQuotedStringTokenCodePoints(value)) {
- throw new Error(`Invalid MIME type parameter value "${value}": only HTTP quoted-string token code points are ` +
- `valid.`);
- }
-
- return this._map.set(name, value);
- }
-
- clear() {
- this._map.clear();
- }
-
- delete(name) {
- name = asciiLowercase(String(name));
- return this._map.delete(name);
- }
-
- forEach(callbackFn, thisArg) {
- this._map.forEach(callbackFn, thisArg);
- }
-
- keys() {
- return this._map.keys();
- }
-
- values() {
- return this._map.values();
- }
-
- entries() {
- return this._map.entries();
- }
-
- [Symbol.iterator]() {
- return this._map[Symbol.iterator]();
- }
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/mime-type.js b/vanilla/node_modules/whatwg-mimetype/lib/mime-type.js
deleted file mode 100644
index 7cdf038..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/mime-type.js
+++ /dev/null
@@ -1,127 +0,0 @@
-"use strict";
-const MIMETypeParameters = require("./mime-type-parameters.js");
-const parse = require("./parser.js");
-const serialize = require("./serializer.js");
-const {
- asciiLowercase,
- solelyContainsHTTPTokenCodePoints
-} = require("./utils.js");
-
-module.exports = class MIMEType {
- constructor(string) {
- string = String(string);
- const result = parse(string);
- if (result === null) {
- throw new Error(`Could not parse MIME type string "${string}"`);
- }
-
- this._type = result.type;
- this._subtype = result.subtype;
- this._parameters = new MIMETypeParameters(result.parameters);
- }
-
- static parse(string) {
- try {
- return new this(string);
- } catch {
- return null;
- }
- }
-
- get essence() {
- return `${this.type}/${this.subtype}`;
- }
-
- get type() {
- return this._type;
- }
-
- set type(value) {
- value = asciiLowercase(String(value));
-
- if (value.length === 0) {
- throw new Error("Invalid type: must be a non-empty string");
- }
- if (!solelyContainsHTTPTokenCodePoints(value)) {
- throw new Error(`Invalid type ${value}: must contain only HTTP token code points`);
- }
-
- this._type = value;
- }
-
- get subtype() {
- return this._subtype;
- }
-
- set subtype(value) {
- value = asciiLowercase(String(value));
-
- if (value.length === 0) {
- throw new Error("Invalid subtype: must be a non-empty string");
- }
- if (!solelyContainsHTTPTokenCodePoints(value)) {
- throw new Error(`Invalid subtype ${value}: must contain only HTTP token code points`);
- }
-
- this._subtype = value;
- }
-
- get parameters() {
- return this._parameters;
- }
-
- toString() {
- // The serialize function works on both "MIME type records" (i.e. the results of parse) and on this class, since
- // this class's interface is identical.
- return serialize(this);
- }
-
- isJavaScript({ prohibitParameters = false } = {}) {
- 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 !prohibitParameters || this._parameters.size === 0;
- }
- default: {
- return false;
- }
- }
- }
- case "application": {
- switch (this._subtype) {
- case "ecmascript":
- case "javascript":
- case "x-ecmascript":
- case "x-javascript": {
- return !prohibitParameters || this._parameters.size === 0;
- }
- default: {
- return false;
- }
- }
- }
- default: {
- return false;
- }
- }
- }
- isXML() {
- return (this._subtype === "xml" && (this._type === "text" || this._type === "application")) ||
- this._subtype.endsWith("+xml");
- }
- isHTML() {
- return this._subtype === "html" && this._type === "text";
- }
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/parser.js b/vanilla/node_modules/whatwg-mimetype/lib/parser.js
deleted file mode 100644
index 8eddbaf..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/parser.js
+++ /dev/null
@@ -1,105 +0,0 @@
-"use strict";
-const {
- removeLeadingAndTrailingHTTPWhitespace,
- removeTrailingHTTPWhitespace,
- isHTTPWhitespaceChar,
- solelyContainsHTTPTokenCodePoints,
- soleyContainsHTTPQuotedStringTokenCodePoints,
- asciiLowercase,
- collectAnHTTPQuotedString
-} = require("./utils.js");
-
-module.exports = input => {
- input = removeLeadingAndTrailingHTTPWhitespace(input);
-
- let position = 0;
- let type = "";
- while (position < input.length && input[position] !== "/") {
- type += input[position];
- ++position;
- }
-
- if (type.length === 0 || !solelyContainsHTTPTokenCodePoints(type)) {
- return null;
- }
-
- if (position >= input.length) {
- return null;
- }
-
- // Skips past "/"
- ++position;
-
- let subtype = "";
- while (position < input.length && input[position] !== ";") {
- subtype += input[position];
- ++position;
- }
-
- subtype = removeTrailingHTTPWhitespace(subtype);
-
- if (subtype.length === 0 || !solelyContainsHTTPTokenCodePoints(subtype)) {
- return null;
- }
-
- const mimeType = {
- type: asciiLowercase(type),
- subtype: asciiLowercase(subtype),
- parameters: new Map()
- };
-
- while (position < input.length) {
- // Skip past ";"
- ++position;
-
- while (isHTTPWhitespaceChar(input[position])) {
- ++position;
- }
-
- let parameterName = "";
- while (position < input.length && input[position] !== ";" && input[position] !== "=") {
- parameterName += input[position];
- ++position;
- }
- parameterName = asciiLowercase(parameterName);
-
- if (position < input.length) {
- if (input[position] === ";") {
- continue;
- }
-
- // Skip past "="
- ++position;
- }
-
- let parameterValue = null;
- if (input[position] === "\"") {
- [parameterValue, position] = collectAnHTTPQuotedString(input, position);
-
- while (position < input.length && input[position] !== ";") {
- ++position;
- }
- } else {
- parameterValue = "";
- while (position < input.length && input[position] !== ";") {
- parameterValue += input[position];
- ++position;
- }
-
- parameterValue = removeTrailingHTTPWhitespace(parameterValue);
-
- if (parameterValue === "") {
- continue;
- }
- }
-
- if (parameterName.length > 0 &&
- solelyContainsHTTPTokenCodePoints(parameterName) &&
- soleyContainsHTTPQuotedStringTokenCodePoints(parameterValue) &&
- !mimeType.parameters.has(parameterName)) {
- mimeType.parameters.set(parameterName, parameterValue);
- }
- }
-
- return mimeType;
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/serializer.js b/vanilla/node_modules/whatwg-mimetype/lib/serializer.js
deleted file mode 100644
index 2d7aaf0..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/serializer.js
+++ /dev/null
@@ -1,25 +0,0 @@
-"use strict";
-const { solelyContainsHTTPTokenCodePoints } = require("./utils.js");
-
-module.exports = mimeType => {
- let serialization = `${mimeType.type}/${mimeType.subtype}`;
-
- if (mimeType.parameters.size === 0) {
- return serialization;
- }
-
- for (let [name, value] of mimeType.parameters) {
- serialization += ";";
- serialization += name;
- serialization += "=";
-
- if (!solelyContainsHTTPTokenCodePoints(value) || value.length === 0) {
- value = value.replace(/(["\\])/ug, "\\$1");
- value = `"${value}"`;
- }
-
- serialization += value;
- }
-
- return serialization;
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/sniff.js b/vanilla/node_modules/whatwg-mimetype/lib/sniff.js
deleted file mode 100644
index 42a86ad..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/sniff.js
+++ /dev/null
@@ -1,751 +0,0 @@
-"use strict";
-const MIMEType = require("./mime-type.js");
-
-// Normalize a MIME type input (string or MIMEType-like object) to a MIMEType.
-// Returns null if parsing fails (including for undefined input).
-function normalizeMIMEType(input) {
- return MIMEType.parse(`${input}`);
-}
-
-// https://mimesniff.spec.whatwg.org/#xml-mime-type
-function isXMLMIMEType(mimeType) {
- return mimeType.subtype.endsWith("+xml") ||
- (mimeType.type === "text" && mimeType.subtype === "xml") ||
- (mimeType.type === "application" && mimeType.subtype === "xml");
-}
-
-// https://mimesniff.spec.whatwg.org/#html-mime-type
-function isHTMLMIMEType(mimeType) {
- return mimeType.type === "text" && mimeType.subtype === "html";
-}
-
-// https://mimesniff.spec.whatwg.org/#resource-header
-const RESOURCE_HEADER_LENGTH = 1445;
-
-function getResourceHeader(resource) {
- if (resource.length <= RESOURCE_HEADER_LENGTH) {
- return resource;
- }
- return resource.subarray(0, RESOURCE_HEADER_LENGTH);
-}
-
-// https://mimesniff.spec.whatwg.org/#image-mime-type
-function isImageMIMEType(mimeType) {
- return mimeType.type === "image";
-}
-
-// https://mimesniff.spec.whatwg.org/#audio-or-video-mime-type
-function isAudioOrVideoMIMEType(mimeType) {
- return mimeType.type === "audio" ||
- mimeType.type === "video" ||
- (mimeType.type === "application" && mimeType.subtype === "ogg");
-}
-
-// https://mimesniff.spec.whatwg.org/#whitespace-byte
-function isWhitespaceByte(byte) {
- return byte === 0x09 || byte === 0x0A || byte === 0x0C || byte === 0x0D || byte === 0x20;
-}
-
-// https://mimesniff.spec.whatwg.org/#binary-data-byte
-function isBinaryDataByte(byte) {
- return (byte >= 0x00 && byte <= 0x08) ||
- byte === 0x0B ||
- (byte >= 0x0E && byte <= 0x1A) ||
- (byte >= 0x1C && byte <= 0x1F);
-}
-
-// https://mimesniff.spec.whatwg.org/#pattern-matching-algorithm
-function matchesSignature(resource, signature) {
- const { pattern, mask, ignoredLeadingBytes, mimeType } = signature;
-
- let s = 0;
- if (ignoredLeadingBytes) {
- while (s < resource.length && ignoredLeadingBytes(resource[s])) {
- s++;
- }
- }
-
- if (resource.length < s + pattern.length) {
- return null;
- }
-
- for (let i = 0; i < pattern.length; i++) {
- if ((resource[s + i] & mask[i]) !== (pattern[i] & mask[i])) {
- return null;
- }
- }
-
- return mimeType;
-}
-
-// https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type
-const step1Table = [
- // <!DOCTYPE HTML TT
- {
- pattern: [0x3C, 0x21, 0x44, 0x4F, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x48, 0x54, 0x4D, 0x4C, 0x20],
- mask: [0xFF, 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <HTML TT
- {
- pattern: [0x3C, 0x48, 0x54, 0x4D, 0x4C, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <HEAD TT
- {
- pattern: [0x3C, 0x48, 0x45, 0x41, 0x44, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <SCRIPT TT
- {
- pattern: [0x3C, 0x53, 0x43, 0x52, 0x49, 0x50, 0x54, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <IFRAME TT
- {
- pattern: [0x3C, 0x49, 0x46, 0x52, 0x41, 0x4D, 0x45, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <H1 TT
- {
- pattern: [0x3C, 0x48, 0x31, 0x20],
- mask: [0xFF, 0xDF, 0xFF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <DIV TT
- {
- pattern: [0x3C, 0x44, 0x49, 0x56, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <FONT TT
- {
- pattern: [0x3C, 0x46, 0x4F, 0x4E, 0x54, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <TABLE TT
- {
- pattern: [0x3C, 0x54, 0x41, 0x42, 0x4C, 0x45, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <A TT
- {
- pattern: [0x3C, 0x41, 0x20],
- mask: [0xFF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <STYLE TT
- {
- pattern: [0x3C, 0x53, 0x54, 0x59, 0x4C, 0x45, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <TITLE TT
- {
- pattern: [0x3C, 0x54, 0x49, 0x54, 0x4C, 0x45, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <B TT
- {
- pattern: [0x3C, 0x42, 0x20],
- mask: [0xFF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <BODY TT
- {
- pattern: [0x3C, 0x42, 0x4F, 0x44, 0x59, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <BR TT
- {
- pattern: [0x3C, 0x42, 0x52, 0x20],
- mask: [0xFF, 0xDF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <P TT
- {
- pattern: [0x3C, 0x50, 0x20],
- mask: [0xFF, 0xDF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <!-- TT
- {
- pattern: [0x3C, 0x21, 0x2D, 0x2D, 0x20],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xE1],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/html"
- },
- // <?xml
- {
- pattern: [0x3C, 0x3F, 0x78, 0x6D, 0x6C],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- ignoredLeadingBytes: isWhitespaceByte,
- mimeType: "text/xml"
- },
- // %PDF-
- {
- pattern: [0x25, 0x50, 0x44, 0x46, 0x2D],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "application/pdf"
- }
-];
-
-// https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type
-const step2Table = [
- // %!PS-Adobe-
- {
- pattern: [0x25, 0x21, 0x50, 0x53, 0x2D, 0x41, 0x64, 0x6F, 0x62, 0x65, 0x2D],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "application/postscript"
- },
- // UTF-16BE BOM
- {
- pattern: [0xFE, 0xFF, 0x00, 0x00],
- mask: [0xFF, 0xFF, 0x00, 0x00],
- mimeType: "text/plain"
- },
- // UTF-16LE BOM
- {
- pattern: [0xFF, 0xFE, 0x00, 0x00],
- mask: [0xFF, 0xFF, 0x00, 0x00],
- mimeType: "text/plain"
- },
- // UTF-8 BOM
- {
- pattern: [0xEF, 0xBB, 0xBF, 0x00],
- mask: [0xFF, 0xFF, 0xFF, 0x00],
- mimeType: "text/plain"
- }
-];
-
-// https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern
-const imageSignatures = [
- { pattern: [0x00, 0x00, 0x01, 0x00], mask: [0xFF, 0xFF, 0xFF, 0xFF], mimeType: "image/x-icon" },
- { pattern: [0x00, 0x00, 0x02, 0x00], mask: [0xFF, 0xFF, 0xFF, 0xFF], mimeType: "image/x-icon" },
- { pattern: [0x42, 0x4D], mask: [0xFF, 0xFF], mimeType: "image/bmp" },
- {
- pattern: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "image/gif"
- },
- {
- pattern: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "image/gif"
- },
- {
- pattern: [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "image/webp"
- },
- {
- pattern: [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "image/png"
- },
- { pattern: [0xFF, 0xD8, 0xFF], mask: [0xFF, 0xFF, 0xFF], mimeType: "image/jpeg" }
-];
-
-// https://mimesniff.spec.whatwg.org/#matching-an-audio-or-video-type-pattern
-const audioVideoSignatures = [
- {
- pattern: [0x46, 0x4F, 0x52, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x41, 0x49, 0x46, 0x46],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "audio/aiff"
- },
- { pattern: [0x49, 0x44, 0x33], mask: [0xFF, 0xFF, 0xFF], mimeType: "audio/mpeg" },
- {
- pattern: [0x4F, 0x67, 0x67, 0x53, 0x00],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "application/ogg"
- },
- {
- pattern: [0x4D, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "audio/midi"
- },
- {
- pattern: [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x41, 0x56, 0x49, 0x20],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "video/avi"
- },
- {
- pattern: [0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "audio/wave"
- }
-];
-
-// https://mimesniff.spec.whatwg.org/#signature-for-mp4
-function matchMP4(resource) {
- if (resource.length < 12) {
- return null;
- }
- // Bytes 4-7 must be "ftyp"
- if (resource[4] !== 0x66 || resource[5] !== 0x74 ||
- resource[6] !== 0x79 || resource[7] !== 0x70) {
- return null;
- }
- const length = (resource[0] << 24) | (resource[1] << 16) | (resource[2] << 8) | resource[3];
- if (length < 12 || length > resource.length) {
- return null;
- }
- const brand = String.fromCharCode(resource[8], resource[9], resource[10], resource[11]);
- const mp4Brands = ["mp41", "mp42", "isom", "iso2", "mmp4", "M4V ", "M4A ", "M4P ", "avc1"];
- if (mp4Brands.includes(brand)) {
- return "video/mp4";
- }
- for (let i = 16; i + 4 <= length && i + 4 <= resource.length; i += 4) {
- const compat = String.fromCharCode(resource[i], resource[i + 1], resource[i + 2], resource[i + 3]);
- if (mp4Brands.includes(compat)) {
- return "video/mp4";
- }
- }
- return null;
-}
-
-// https://mimesniff.spec.whatwg.org/#parse-a-vint
-//
-// Note: The spec has a bug: it takes an "iter" parameter but never uses it, always starting from index 0.
-// See https://github.com/whatwg/mimesniff/issues/167. We implement the intended behavior.
-//
-// The spec algorithm also does extra processing which is not actually needed by its single caller:
-// https://github.com/whatwg/mimesniff/issues/146. We omit that processing.
-function parseVint(sequence, iter) {
- let mask = 128;
- const maxVintLength = 8;
- let numberSize = 1;
- while (numberSize < maxVintLength && numberSize < sequence.length) {
- if ((sequence[iter] & mask) !== 0) {
- break;
- }
- mask >>= 1;
- ++numberSize;
- }
- return numberSize;
-}
-
-// https://mimesniff.spec.whatwg.org/#matching-a-padded-sequence
-function matchPaddedSequence(sequence, offset, pattern) {
- // Skip leading 0x00 bytes
- while (offset < sequence.length && sequence[offset] === 0x00) {
- offset++;
- }
- // Check if pattern matches at current offset
- if (sequence.length < offset + pattern.length) {
- return false;
- }
- for (let i = 0; i < pattern.length; i++) {
- if (sequence[offset + i] !== pattern[i]) {
- return false;
- }
- }
- return true;
-}
-
-// https://mimesniff.spec.whatwg.org/#signature-for-webm
-function matchWebM(resource) {
- const { length } = resource;
- // Step 3: If length < 4, return false
- if (length < 4) {
- return null;
- }
- // Step 4: Check EBML header 0x1A 0x45 0xDF 0xA3
- if (resource[0] !== 0x1A || resource[1] !== 0x45 ||
- resource[2] !== 0xDF || resource[3] !== 0xA3) {
- return null;
- }
- // Step 5-6: Search for DocType element (0x42 0x82) in bytes 4-37
- let iter = 4;
- while (iter < length && iter < 38) {
- if (iter + 1 < length && resource[iter] === 0x42 && resource[iter + 1] === 0x82) {
- iter += 2;
- if (iter >= length) {
- break;
- }
- const numberSize = parseVint(resource, iter);
- iter += numberSize;
- if (iter >= length - 4) {
- break;
- }
- // Match padded sequence "webm" (0x77 0x65 0x62 0x6D)
- if (matchPaddedSequence(resource, iter, [0x77, 0x65, 0x62, 0x6D])) {
- return "video/webm";
- }
- }
- iter++;
- }
- return null;
-}
-
-// https://mimesniff.spec.whatwg.org/#signature-for-mp3-without-id3
-
-// Bitrate tables (kbps) indexed by bitrate-index (0-15)
-// https://mimesniff.spec.whatwg.org/#mp3-rates-table
-const mp3Rates = [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0];
-const mp25Rates = [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0];
-
-// Sample rate table indexed by samplerate-index (0-3)
-// https://mimesniff.spec.whatwg.org/#mp3-sample-rate-table
-const sampleRates = [44100, 48000, 32000, 0];
-
-// https://mimesniff.spec.whatwg.org/#match-an-mp3-header
-function matchMP3Header(sequence, s) {
- const { length } = sequence;
- // Step 1: If length < s + 4, return false
- if (length < s + 4) {
- return false;
- }
- // Step 2: If sequence[s] ≠ 0xFF or sequence[s+1] & 0xE0 ≠ 0xE0, return false
- if (sequence[s] !== 0xFF || (sequence[s + 1] & 0xE0) !== 0xE0) {
- return false;
- }
- // Step 3: Extract layer
- const layer = (sequence[s + 1] & 0x06) >> 1;
- // Step 4: If layer is 0, return false
- if (layer === 0) {
- return false;
- }
- // Step 5: Extract bit-rate index, return false if 15
- const bitRate = (sequence[s + 2] & 0xF0) >> 4;
- if (bitRate === 15) {
- return false;
- }
- // Step 6: Extract sample-rate index, return false if 3
- const sampleRate = (sequence[s + 2] & 0x0C) >> 2;
- if (sampleRate === 3) {
- return false;
- }
- // Step 9: Check final-layer (layer must be 3 for MP3)
- const finalLayer = (4 - layer) & 0x03;
- if (finalLayer !== 3) {
- return false;
- }
- // Step 10: Return true
- return true;
-}
-
-// https://mimesniff.spec.whatwg.org/#parse-an-mp3-frame
-function parseMP3Frame(sequence, s) {
- // Step 1: Extract version
- const version = (sequence[s + 1] & 0x18) >> 3;
- // Step 2: Extract bitrate-index
- const bitrateIndex = (sequence[s + 2] & 0xF0) >> 4;
- // Step 3+4: Get bitrate from appropriate table
- const bitrate = (version & 0x01) !== 0 ? mp3Rates[bitrateIndex] : mp25Rates[bitrateIndex];
- // Step 5: Extract samplerate-index
- const samplerateIndex = (sequence[s + 2] & 0x0C) >> 2;
- // Step 6: Get samplerate
- const samplerate = sampleRates[samplerateIndex];
- // Step 7: Extract pad
- const pad = (sequence[s + 2] & 0x02) >> 1;
-
- return { version, bitrate, samplerate, pad };
-}
-
-// https://mimesniff.spec.whatwg.org/#compute-an-mp3-frame-size
-function computeMP3FrameSize(version, bitrate, samplerate, pad) {
- // Step 1: Determine scale based on version
- const scale = version === 1 ? 72 : 144;
- // Step 2: Compute size
- let size = Math.floor((bitrate * 1000 * scale) / samplerate);
- // Step 3: Add padding if present
- if (pad !== 0) {
- size += 1;
- }
- // Step 4: Return size
- return size;
-}
-
-// https://mimesniff.spec.whatwg.org/#signature-for-mp3-without-id3
-function matchMP3WithoutID3(resource) {
- const { length } = resource;
- // Step 2: Let s be 0
- let s = 0;
- // Step 3: If match mp3 header returns false, return false
- if (!matchMP3Header(resource, s)) {
- return null;
- }
- // Step 4: Parse an mp3 frame
- const { version, bitrate, samplerate, pad } = parseMP3Frame(resource, s);
- // Step 5: Compute frame size
- const skippedBytes = computeMP3FrameSize(version, bitrate, samplerate, pad);
- // Step 6: If skipped-bytes < 4 or skipped-bytes > length - s, return false
- if (skippedBytes < 4 || skippedBytes > length - s) {
- return null;
- }
- // Step 7: Increment s by skipped-bytes
- s += skippedBytes;
- // Step 8: If match mp3 header returns false, return false; otherwise return true
- if (!matchMP3Header(resource, s)) {
- return null;
- }
- return "audio/mpeg";
-}
-
-// https://mimesniff.spec.whatwg.org/#matching-an-archive-type-pattern
-const archiveSignatures = [
- { pattern: [0x1F, 0x8B, 0x08], mask: [0xFF, 0xFF, 0xFF], mimeType: "application/x-gzip" },
- { pattern: [0x50, 0x4B, 0x03, 0x04], mask: [0xFF, 0xFF, 0xFF, 0xFF], mimeType: "application/zip" },
- {
- pattern: [0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00],
- mask: [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
- mimeType: "application/x-rar-compressed"
- }
-];
-
-// https://mimesniff.spec.whatwg.org/#matching-an-image-type-pattern
-function matchImageType(resource) {
- for (const sig of imageSignatures) {
- const result = matchesSignature(resource, sig);
- if (result) {
- return result;
- }
- }
- return null;
-}
-
-// https://mimesniff.spec.whatwg.org/#matching-an-audio-or-video-type-pattern
-function matchAudioOrVideoType(resource) {
- for (const sig of audioVideoSignatures) {
- const result = matchesSignature(resource, sig);
- if (result) {
- return result;
- }
- }
- const mp4Result = matchMP4(resource);
- if (mp4Result) {
- return mp4Result;
- }
- const webmResult = matchWebM(resource);
- if (webmResult) {
- return webmResult;
- }
- const mp3Result = matchMP3WithoutID3(resource);
- if (mp3Result) {
- return mp3Result;
- }
- return null;
-}
-
-// https://mimesniff.spec.whatwg.org/#rules-for-text-or-binary
-function distinguishTextOrBinary(resourceHeader) {
- // Step 1: Let length be the number of bytes in the resource header.
- const { length } = resourceHeader;
-
- // Step 2: If the first 2 bytes match a UTF-16 BOM, return "text/plain".
- if (length >= 2) {
- // UTF-16 BE BOM
- if (resourceHeader[0] === 0xFE && resourceHeader[1] === 0xFF) {
- return "text/plain";
- }
- // UTF-16 LE BOM
- if (resourceHeader[0] === 0xFF && resourceHeader[1] === 0xFE) {
- return "text/plain";
- }
- }
-
- // Step 3: If the first 3 bytes match the UTF-8 BOM, return "text/plain".
- if (length >= 3) {
- if (resourceHeader[0] === 0xEF && resourceHeader[1] === 0xBB && resourceHeader[2] === 0xBF) {
- return "text/plain";
- }
- }
-
- // Step 4: If the resource header contains no binary data bytes, return "text/plain".
- for (let i = 0; i < length; i++) {
- if (isBinaryDataByte(resourceHeader[i])) {
- // Step 5: Return "application/octet-stream".
- return "application/octet-stream";
- }
- }
-
- return "text/plain";
-}
-
-// https://mimesniff.spec.whatwg.org/#rules-for-identifying-an-unknown-mime-type
-function identifyAnUnknownMIMEType(resourceHeader, { sniffScriptable = false } = {}) {
- // Step 1
- if (sniffScriptable) {
- for (const sig of step1Table) {
- const result = matchesSignature(resourceHeader, sig);
- if (result) {
- return result;
- }
- }
- }
-
- // Step 2
- for (const sig of step2Table) {
- const result = matchesSignature(resourceHeader, sig);
- if (result) {
- return result;
- }
- }
-
- // Step 3: image type pattern matching
- for (const sig of imageSignatures) {
- const result = matchesSignature(resourceHeader, sig);
- if (result) {
- return result;
- }
- }
-
- // Step 4: audio/video type pattern matching
- // https://mimesniff.spec.whatwg.org/#matching-an-audio-or-video-type-pattern
- for (const sig of audioVideoSignatures) {
- const result = matchesSignature(resourceHeader, sig);
- if (result) {
- return result;
- }
- }
- // Then check MP4, WebM, and MP3-without-ID3 signatures
- const mp4Result = matchMP4(resourceHeader);
- if (mp4Result) {
- return mp4Result;
- }
- const webmResult = matchWebM(resourceHeader);
- if (webmResult) {
- return webmResult;
- }
- const mp3Result = matchMP3WithoutID3(resourceHeader);
- if (mp3Result) {
- return mp3Result;
- }
-
- // Step 5: archive type pattern matching
- for (const sig of archiveSignatures) {
- const result = matchesSignature(resourceHeader, sig);
- if (result) {
- return result;
- }
- }
-
- // Step 6: If resource header contains no binary data bytes, return text/plain
- for (let i = 0; i < resourceHeader.length; i++) {
- if (isBinaryDataByte(resourceHeader[i])) {
- // Step 7: return application/octet-stream
- return "application/octet-stream";
- }
- }
-
- return "text/plain";
-}
-
-// Apache bug values that trigger text/binary sniffing
-// https://mimesniff.spec.whatwg.org/#supplied-mime-type-detection-algorithm
-const apacheBugValues = new Set([
- "text/plain",
- "text/plain; charset=ISO-8859-1",
- "text/plain; charset=iso-8859-1",
- "text/plain; charset=UTF-8"
-]);
-
-// https://mimesniff.spec.whatwg.org/#supplied-mime-type-detection-algorithm
-function detectSuppliedMIMEType({ contentTypeHeader, providedType }) {
- let suppliedMIMEType = null;
- let checkForApacheBug = false;
-
- if (contentTypeHeader !== undefined) {
- // Step 2: HTTP Content-Type header
- suppliedMIMEType = normalizeMIMEType(contentTypeHeader);
- if (suppliedMIMEType !== null && typeof contentTypeHeader === "string") {
- checkForApacheBug = apacheBugValues.has(contentTypeHeader);
- }
- } else if (providedType !== undefined) {
- // Steps 3-4: Filesystem or other protocol
- suppliedMIMEType = normalizeMIMEType(providedType);
- }
- // Step 5: If parsing failed, suppliedMIMEType remains null (undefined per spec)
-
- return { suppliedMIMEType, checkForApacheBug };
-}
-
-/**
- * Determine the computed MIME type of a resource.
- * https://mimesniff.spec.whatwg.org/#determining-the-computed-mime-type-of-a-resource
- *
- * @param {Uint8Array} resource - The resource bytes
- * @param {object} options - Options object
- * @param {string} options.contentTypeHeader - The Content-Type header value (for HTTP resources)
- * @param {string} options.providedType - MIME type from filesystem or other protocol (for non-HTTP resources)
- * @param {boolean} options.noSniff - Whether the X-Content-Type-Options: nosniff header was present
- * @param {function} options.isSupported - Predicate to check if an image/audio/video MIME type is supported
- * @returns {MIMEType} The computed MIME type
- */
-module.exports = function computedMIMEType(
- resource,
- { contentTypeHeader, providedType, noSniff = false, isSupported = () => true } = {}
-) {
- const resourceHeader = getResourceHeader(resource);
- const { suppliedMIMEType, checkForApacheBug } = detectSuppliedMIMEType({ contentTypeHeader, providedType });
-
- // Step 1: If the supplied MIME type is an XML MIME type or HTML MIME type, return it
- if (suppliedMIMEType !== null && (isXMLMIMEType(suppliedMIMEType) || isHTMLMIMEType(suppliedMIMEType))) {
- return suppliedMIMEType;
- }
-
- // Step 2: If supplied MIME type is undefined, or its essence is "unknown/unknown",
- // "application/unknown", or "*/*", execute rules for identifying an unknown MIME type
- if (suppliedMIMEType === null ||
- suppliedMIMEType.essence === "unknown/unknown" ||
- suppliedMIMEType.essence === "application/unknown" ||
- suppliedMIMEType.essence === "*/*") {
- // sniff-scriptable flag is the inverse of no-sniff flag
- return new MIMEType(identifyAnUnknownMIMEType(resourceHeader, { sniffScriptable: !noSniff }));
- }
-
- // Step 3: If the no-sniff flag is set, return the supplied MIME type
- if (noSniff) {
- return suppliedMIMEType;
- }
-
- // Step 4: If the check-for-apache-bug flag is set, execute rules for distinguishing
- // if a resource is text or binary
- if (checkForApacheBug) {
- return new MIMEType(distinguishTextOrBinary(resourceHeader));
- }
-
- // Steps 5-6: If supplied MIME type is a supported image MIME type, execute image pattern matching
- if (isImageMIMEType(suppliedMIMEType) && isSupported(suppliedMIMEType)) {
- const imageResult = matchImageType(resourceHeader);
- if (imageResult !== null) {
- return new MIMEType(imageResult);
- }
- }
-
- // Steps 7-8: If supplied MIME type is a supported audio/video type, execute audio/video matching
- if (isAudioOrVideoMIMEType(suppliedMIMEType) && isSupported(suppliedMIMEType)) {
- const avResult = matchAudioOrVideoType(resourceHeader);
- if (avResult !== null) {
- return new MIMEType(avResult);
- }
- }
-
- // Step 9: Return the supplied MIME type
- return suppliedMIMEType;
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/lib/utils.js b/vanilla/node_modules/whatwg-mimetype/lib/utils.js
deleted file mode 100644
index 5a814fc..0000000
--- a/vanilla/node_modules/whatwg-mimetype/lib/utils.js
+++ /dev/null
@@ -1,60 +0,0 @@
-"use strict";
-
-exports.removeLeadingAndTrailingHTTPWhitespace = string => {
- return string.replace(/^[ \t\n\r]+/u, "").replace(/[ \t\n\r]+$/u, "");
-};
-
-exports.removeTrailingHTTPWhitespace = string => {
- return string.replace(/[ \t\n\r]+$/u, "");
-};
-
-exports.isHTTPWhitespaceChar = char => {
- return char === " " || char === "\t" || char === "\n" || char === "\r";
-};
-
-exports.solelyContainsHTTPTokenCodePoints = string => {
- return /^[-!#$%&'*+.^_`|~A-Za-z0-9]*$/u.test(string);
-};
-
-exports.soleyContainsHTTPQuotedStringTokenCodePoints = string => {
- return /^[\t\u0020-\u007E\u0080-\u00FF]*$/u.test(string);
-};
-
-exports.asciiLowercase = string => {
- return string.replace(/[A-Z]/ug, l => l.toLowerCase());
-};
-
-// This variant only implements it with the extract-value flag set.
-exports.collectAnHTTPQuotedString = (input, position) => {
- let value = "";
-
- position++;
-
- while (true) {
- while (position < input.length && input[position] !== "\"" && input[position] !== "\\") {
- value += input[position];
- ++position;
- }
-
- if (position >= input.length) {
- break;
- }
-
- const quoteOrBackslash = input[position];
- ++position;
-
- if (quoteOrBackslash === "\\") {
- if (position >= input.length) {
- value += "\\";
- break;
- }
-
- value += input[position];
- ++position;
- } else {
- break;
- }
- }
-
- return [value, position];
-};
diff --git a/vanilla/node_modules/whatwg-mimetype/package.json b/vanilla/node_modules/whatwg-mimetype/package.json
deleted file mode 100644
index a37f297..0000000
--- a/vanilla/node_modules/whatwg-mimetype/package.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "name": "whatwg-mimetype",
- "description": "Parses, serializes, and manipulates MIME types, according to the WHATWG MIME Sniffing Standard",
- "keywords": [
- "content-type",
- "mime type",
- "mimesniff",
- "http",
- "whatwg"
- ],
- "version": "5.0.0",
- "author": "Domenic Denicola <d@domenic.me> (https://domenic.me/)",
- "license": "MIT",
- "repository": "jsdom/whatwg-mimetype",
- "main": "lib/index.js",
- "files": [
- "lib/"
- ],
- "scripts": {
- "test": "node --test",
- "coverage": "c8 node --test --experimental-test-coverage",
- "lint": "eslint",
- "pretest": "node scripts/get-latest-platform-tests.mjs"
- },
- "devDependencies": {
- "@domenic/eslint-config": "^4.0.1",
- "@exodus/bytes": "^1.9.0",
- "c8": "^10.1.3",
- "eslint": "^9.39.2",
- "printable-string": "^0.3.0"
- },
- "engines": {
- "node": ">=20"
- },
- "c8": {
- "reporter": [
- "html"
- ],
- "exclude": [
- "scripts/",
- "test/"
- ]
- }
-}