@depup/file-type 22.0.1-depup.0 → 22.1.0-depup.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/README.md +2 -2
- package/changes.json +1 -1
- package/package.json +5 -4
- package/readme.md +6 -0
- package/source/detectors/zip.js +6 -1
- package/source/index.d.ts +3 -0
- package/source/index.js +53 -14
- package/source/supported.js +2 -0
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@ npm install @depup/file-type
|
|
|
13
13
|
|
|
14
14
|
| Field | Value |
|
|
15
15
|
|-------|-------|
|
|
16
|
-
| Original | [file-type](https://www.npmjs.com/package/file-type) @ 22.0
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [file-type](https://www.npmjs.com/package/file-type) @ 22.1.0 |
|
|
17
|
+
| Processed | 2026-09-11 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 0 |
|
|
20
20
|
|
package/changes.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@depup/file-type",
|
|
3
|
-
"version": "22.0
|
|
3
|
+
"version": "22.1.0-depup.0",
|
|
4
4
|
"description": "Detect the file type of a file, stream, or data (with updated dependencies)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/file-type",
|
|
@@ -236,7 +236,8 @@
|
|
|
236
236
|
"dat",
|
|
237
237
|
"key",
|
|
238
238
|
"numbers",
|
|
239
|
-
"pages"
|
|
239
|
+
"pages",
|
|
240
|
+
"iso"
|
|
240
241
|
],
|
|
241
242
|
"dependencies": {
|
|
242
243
|
"@tokenizer/inflate": "^0.4.1",
|
|
@@ -283,8 +284,8 @@
|
|
|
283
284
|
"changes": {},
|
|
284
285
|
"depsUpdated": 0,
|
|
285
286
|
"originalPackage": "file-type",
|
|
286
|
-
"originalVersion": "22.0
|
|
287
|
-
"processedAt": "2026-
|
|
287
|
+
"originalVersion": "22.1.0",
|
|
288
|
+
"processedAt": "2026-09-11T16:12:10.970Z",
|
|
288
289
|
"smokeTest": "passed"
|
|
289
290
|
}
|
|
290
291
|
}
|
package/readme.md
CHANGED
|
@@ -306,6 +306,9 @@ They allow support for uncommon file types, non-binary formats, or customized de
|
|
|
306
306
|
Detectors can be added via the constructor options or by directly modifying `FileTypeParser#detectors`.
|
|
307
307
|
Detectors provided through the constructor are executed before the default ones.
|
|
308
308
|
|
|
309
|
+
> [!NOTE]
|
|
310
|
+
> Not safe for concurrent use. Create a new instance per call if you need concurrency.
|
|
311
|
+
|
|
309
312
|
### Example adding a detector
|
|
310
313
|
|
|
311
314
|
```js
|
|
@@ -461,6 +464,7 @@ MIME media subtypes prefixed with `x-ft-` are custom and defined by us. They are
|
|
|
461
464
|
- [`ico`](https://en.wikipedia.org/wiki/ICO_(file_format)) - Windows icon file
|
|
462
465
|
- [`ics`](https://en.wikipedia.org/wiki/ICalendar#Data_format) - iCalendar
|
|
463
466
|
- [`indd`](https://en.wikipedia.org/wiki/Adobe_InDesign#File_format) - Adobe InDesign document
|
|
467
|
+
- [`iso`](https://en.wikipedia.org/wiki/ISO_9660) - ISO 9660 disc image
|
|
464
468
|
- [`it`](https://wiki.openmpt.org/Manual:_Module_formats#The_Impulse_Tracker_format_.28.it.29) - Audio module format: Impulse Tracker
|
|
465
469
|
- [`j2c`](https://en.wikipedia.org/wiki/JPEG_2000) - JPEG 2000
|
|
466
470
|
- [`jar`](https://en.wikipedia.org/wiki/JAR_(file_format)) - Java archive
|
|
@@ -575,6 +579,8 @@ MIME media subtypes prefixed with `x-ft-` are custom and defined by us. They are
|
|
|
575
579
|
- [`zip`](https://en.wikipedia.org/wiki/Zip_(file_format)) - Archive file
|
|
576
580
|
- [`zst`](https://en.wikipedia.org/wiki/Zstandard) - Archive file
|
|
577
581
|
|
|
582
|
+
ISO 9660 requires random-access input or `fileTypeStream()` with `sampleSize >= 32_774`; `fileTypeFromStream()` is unsupported.
|
|
583
|
+
|
|
578
584
|
*[Pull requests](.github/pull_request_template.md) are welcome for additional commonly used file types.*
|
|
579
585
|
|
|
580
586
|
The following file types will not be accepted, but most of them are supported by [third-party detectors](#available-third-party-file-type-detectors).
|
package/source/detectors/zip.js
CHANGED
|
@@ -53,12 +53,17 @@ async function decompressDeflateRawWithLimit(data, {maximumLength = maximumZipEn
|
|
|
53
53
|
|
|
54
54
|
totalLength += value.length;
|
|
55
55
|
if (totalLength > maximumLength) {
|
|
56
|
-
await reader.cancel();
|
|
56
|
+
await reader.cancel().catch(() => {});
|
|
57
57
|
throw new Error(`ZIP entry decompressed data exceeds ${maximumLength} bytes`);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
chunks.push(value);
|
|
61
61
|
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
// A ZIP entry with a data descriptor has an unknown compressed size, so the buffered data can contain bytes that follow the deflate stream. Node.js 24 rejects those, unlike other versions. The data decompressed so far is still valid and enough for detection.
|
|
64
|
+
if (error.code !== 'ERR_TRAILING_JUNK_AFTER_STREAM_END') {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
62
67
|
} finally {
|
|
63
68
|
reader.releaseLock();
|
|
64
69
|
}
|
package/source/index.d.ts
CHANGED
|
@@ -238,6 +238,9 @@ This method can be handy to put in a stream pipeline, but it comes with a price.
|
|
|
238
238
|
*/
|
|
239
239
|
export function fileTypeStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions & FileTypeOptions): Promise<AnyWebReadableByteStreamWithFileType>;
|
|
240
240
|
|
|
241
|
+
/**
|
|
242
|
+
Not safe for concurrent use. Create a new instance per call if you need concurrency.
|
|
243
|
+
*/
|
|
241
244
|
export declare class FileTypeParser {
|
|
242
245
|
/**
|
|
243
246
|
File type detectors.
|
package/source/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import {detectPng} from './detectors/png.js';
|
|
|
25
25
|
import {detectAsf} from './detectors/asf.js';
|
|
26
26
|
|
|
27
27
|
export const reasonableDetectionSizeInBytes = 4100; // A fair amount of file-types are detectable within this range.
|
|
28
|
-
const maximumMpegOffsetTolerance = reasonableDetectionSizeInBytes -
|
|
28
|
+
const maximumMpegOffsetTolerance = reasonableDetectionSizeInBytes - 4; // Keep room for the 4 bytes of the frame header at the deepest scanned offset.
|
|
29
29
|
const maximumNestedGzipDetectionSizeInBytes = maximumUntrustedSkipSizeInBytes;
|
|
30
30
|
const maximumNestedGzipProbeDepth = 1;
|
|
31
31
|
const unknownSizeGzipProbeTimeoutInMilliseconds = 100;
|
|
@@ -64,7 +64,7 @@ function getKnownFileSizeOrMaximum(fileSize) {
|
|
|
64
64
|
|
|
65
65
|
// Keep the specifier non-literal at the call site so browser bundlers do not try to resolve Node-only imports.
|
|
66
66
|
function importAtRuntime(specifier) {
|
|
67
|
-
return import(specifier);
|
|
67
|
+
return import(/* @vite-ignore */ /* webpackIgnore: true */ specifier);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
// Wrap stream in an identity TransformStream to avoid BYOB readers.
|
|
@@ -1689,6 +1689,33 @@ export class FileTypeParser {
|
|
|
1689
1689
|
mime: 'application/pgp-encrypted',
|
|
1690
1690
|
};
|
|
1691
1691
|
}
|
|
1692
|
+
|
|
1693
|
+
// ISO 9660 optical disc image: the Volume Descriptor Set starts at sector 16 (2048-byte
|
|
1694
|
+
// sectors). Every descriptor in that set carries the 5-byte standard identifier `CD001`
|
|
1695
|
+
// at offset 1, regardless of descriptor type, so checking the first one is sufficient.
|
|
1696
|
+
// Only attempted for random-access inputs (buffer/file/blob, or a stream sampled with a
|
|
1697
|
+
// large enough `sampleSize`): on an unknown-size stream this offset is far past what's
|
|
1698
|
+
// reasonable to buffer just to rule out one format, so it's left undetected there.
|
|
1699
|
+
const isoStandardIdentifierOffset = 32_769;
|
|
1700
|
+
const isoStandardIdentifierLength = 5;
|
|
1701
|
+
if (
|
|
1702
|
+
tokenizer.supportsRandomAccess()
|
|
1703
|
+
&& tokenizer.fileInfo.size >= (isoStandardIdentifierOffset + isoStandardIdentifierLength)
|
|
1704
|
+
) {
|
|
1705
|
+
const isoStandardIdentifier = new Uint8Array(isoStandardIdentifierLength);
|
|
1706
|
+
await tokenizer.peekBuffer(isoStandardIdentifier, {
|
|
1707
|
+
position: isoStandardIdentifierOffset,
|
|
1708
|
+
length: isoStandardIdentifierLength,
|
|
1709
|
+
mayBeLess: true,
|
|
1710
|
+
});
|
|
1711
|
+
|
|
1712
|
+
if (checkBytes(isoStandardIdentifier, stringToBytes('CD001'))) {
|
|
1713
|
+
return {
|
|
1714
|
+
ext: 'iso',
|
|
1715
|
+
mime: 'application/x-iso9660-image',
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1692
1719
|
};
|
|
1693
1720
|
// Detections with limited supporting data, resulting in a higher likelihood of false positives
|
|
1694
1721
|
detectImprecise = async tokenizer => {
|
|
@@ -1729,11 +1756,11 @@ export class FileTypeParser {
|
|
|
1729
1756
|
};
|
|
1730
1757
|
}
|
|
1731
1758
|
|
|
1732
|
-
// Adjust buffer to `mpegOffsetTolerance
|
|
1733
|
-
await tokenizer.peekBuffer(this.buffer, {length: Math.min(
|
|
1759
|
+
// Adjust buffer to `mpegOffsetTolerance`, plus the 4 bytes of the frame header itself
|
|
1760
|
+
await tokenizer.peekBuffer(this.buffer, {length: Math.min(4 + this.options.mpegOffsetTolerance, fileSize), mayBeLess: true});
|
|
1734
1761
|
|
|
1735
1762
|
// Check MPEG 1 or 2 Layer 3 header, or 'layer 0' for ADTS (MPEG sync-word 0xFFE)
|
|
1736
|
-
if (this.buffer.length >= (
|
|
1763
|
+
if (this.buffer.length >= (4 + this.options.mpegOffsetTolerance)) {
|
|
1737
1764
|
for (let depth = 0; depth <= this.options.mpegOffsetTolerance; ++depth) {
|
|
1738
1765
|
const type = this.scanMpeg(depth);
|
|
1739
1766
|
if (type) {
|
|
@@ -1865,22 +1892,34 @@ export class FileTypeParser {
|
|
|
1865
1892
|
*/
|
|
1866
1893
|
scanMpeg(offset) {
|
|
1867
1894
|
if (this.check([0xFF, 0xE0], {offset, mask: [0xFF, 0xE0]})) {
|
|
1895
|
+
// Both (ADTS) MPEG-2 and MPEG-4 are AAC
|
|
1868
1896
|
if (this.check([0x10], {offset: offset + 1, mask: [0x16]})) {
|
|
1869
|
-
// Check for (ADTS) MPEG-2
|
|
1870
|
-
if (this.check([0x08], {offset: offset + 1, mask: [0x08]})) {
|
|
1871
|
-
return {
|
|
1872
|
-
ext: 'aac',
|
|
1873
|
-
mime: 'audio/aac',
|
|
1874
|
-
};
|
|
1875
|
-
}
|
|
1876
|
-
|
|
1877
|
-
// Must be (ADTS) MPEG-4
|
|
1878
1897
|
return {
|
|
1879
1898
|
ext: 'aac',
|
|
1880
1899
|
mime: 'audio/aac',
|
|
1881
1900
|
};
|
|
1882
1901
|
}
|
|
1883
1902
|
|
|
1903
|
+
// An MPEG-1 Layer I header with CRC protection enabled is byte-identical to a UTF-16 LE BOM, so text files cannot be told apart from audio. `file(1)` disables MPEG-1 Layer I detection completely for this reason; we only drop the colliding variant.
|
|
1904
|
+
if (this.check([0xFF, 0xFE], {offset})) {
|
|
1905
|
+
return;
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
// Reject the reserved MPEG version `01`
|
|
1909
|
+
if (this.check([0x08], {offset: offset + 1, mask: [0x18]})) {
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// Reject the `bad` (`1111`) bitrate index
|
|
1914
|
+
if (this.check([0xF0], {offset: offset + 2, mask: [0xF0]})) {
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
// Reject the reserved sampling frequency `11`
|
|
1919
|
+
if (this.check([0x0C], {offset: offset + 2, mask: [0x0C]})) {
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1922
|
+
|
|
1884
1923
|
// MPEG 1 or 2 Layer 3 header
|
|
1885
1924
|
// Check for MPEG layer 3
|
|
1886
1925
|
if (this.check([0x02], {offset: offset + 1, mask: [0x06]})) {
|
package/source/supported.js
CHANGED
|
@@ -184,6 +184,7 @@ export const extensions = [
|
|
|
184
184
|
'key',
|
|
185
185
|
'numbers',
|
|
186
186
|
'pages',
|
|
187
|
+
'iso',
|
|
187
188
|
];
|
|
188
189
|
|
|
189
190
|
export const mimeTypes = [
|
|
@@ -365,4 +366,5 @@ export const mimeTypes = [
|
|
|
365
366
|
'application/vnd.apple.keynote',
|
|
366
367
|
'application/vnd.apple.numbers',
|
|
367
368
|
'application/vnd.apple.pages',
|
|
369
|
+
'application/x-iso9660-image',
|
|
368
370
|
];
|