file-type 19.3.0 → 19.4.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/core.d.ts +16 -0
- package/core.js +49 -0
- package/index.d.ts +6 -7
- package/index.js +8 -4
- package/package.json +15 -5
- package/readme.md +7 -6
package/core.d.ts
CHANGED
|
@@ -475,6 +475,17 @@ export declare class TokenizerPositionError extends Error {
|
|
|
475
475
|
constructor(message?: string);
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
export type AnyWebReadableByteStreamWithFileType = AnyWebReadableStream<Uint8Array> & {
|
|
479
|
+
readonly fileType?: FileTypeResult;
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
Returns a `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`.
|
|
484
|
+
|
|
485
|
+
This method can be handy to put in a stream pipeline, but it comes with a price. Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type. The sample size impacts the file detection resolution. A smaller sample size will result in lower probability of the best file type detection.
|
|
486
|
+
*/
|
|
487
|
+
export function fileTypeStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
|
|
488
|
+
|
|
478
489
|
export declare class FileTypeParser {
|
|
479
490
|
detectors: Iterable<Detector>;
|
|
480
491
|
|
|
@@ -494,4 +505,9 @@ export declare class FileTypeParser {
|
|
|
494
505
|
Works the same way as {@link fileTypeFromBlob}, additionally taking into account custom detectors (if any were provided to the constructor).
|
|
495
506
|
*/
|
|
496
507
|
fromBlob(blob: Blob): Promise<FileTypeResult | undefined>;
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor).
|
|
511
|
+
*/
|
|
512
|
+
toDetectionStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
|
|
497
513
|
}
|
package/core.js
CHANGED
|
@@ -51,6 +51,10 @@ export async function fileTypeFromTokenizer(tokenizer) {
|
|
|
51
51
|
return new FileTypeParser().fromTokenizer(tokenizer);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
export async function fileTypeStream(webStream) {
|
|
55
|
+
return new FileTypeParser().toDetectionStream(webStream);
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
export class FileTypeParser {
|
|
55
59
|
constructor(options) {
|
|
56
60
|
this.detectors = options?.customDetectors;
|
|
@@ -104,6 +108,51 @@ export class FileTypeParser {
|
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
|
|
111
|
+
async toDetectionStream(stream, options) {
|
|
112
|
+
const {sampleSize = reasonableDetectionSizeInBytes} = options;
|
|
113
|
+
let detectedFileType;
|
|
114
|
+
let firstChunk;
|
|
115
|
+
|
|
116
|
+
const reader = stream.getReader({mode: 'byob'});
|
|
117
|
+
try {
|
|
118
|
+
// Read the first chunk from the stream
|
|
119
|
+
const {value: chunk, done} = await reader.read(new Uint8Array(sampleSize));
|
|
120
|
+
firstChunk = chunk;
|
|
121
|
+
if (!done && chunk) {
|
|
122
|
+
try {
|
|
123
|
+
// Attempt to detect the file type from the chunk
|
|
124
|
+
detectedFileType = await this.fromBuffer(chunk.slice(0, sampleSize));
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (!(error instanceof strtok3.EndOfStreamError)) {
|
|
127
|
+
throw error; // Re-throw non-EndOfStreamError
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
detectedFileType = undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
firstChunk = chunk;
|
|
135
|
+
} finally {
|
|
136
|
+
reader.releaseLock(); // Ensure the reader is released
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Create a new ReadableStream to manage locking issues
|
|
140
|
+
const transformStream = new TransformStream({
|
|
141
|
+
async start(controller) {
|
|
142
|
+
controller.enqueue(firstChunk); // Enqueue the initial chunk
|
|
143
|
+
},
|
|
144
|
+
transform(chunk, controller) {
|
|
145
|
+
// Pass through the chunks without modification
|
|
146
|
+
controller.enqueue(chunk);
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const newStream = stream.pipeThrough(transformStream);
|
|
151
|
+
newStream.fileType = detectedFileType;
|
|
152
|
+
|
|
153
|
+
return newStream;
|
|
154
|
+
}
|
|
155
|
+
|
|
107
156
|
check(header, options) {
|
|
108
157
|
return _check(this.buffer, header, options);
|
|
109
158
|
}
|
package/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ Typings for Node.js specific entry point.
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type {Readable as NodeReadableStream} from 'node:stream';
|
|
6
|
-
import type {FileTypeResult, StreamOptions, AnyWebReadableStream, Detector} from './core.js';
|
|
6
|
+
import type {FileTypeResult, StreamOptions, AnyWebReadableStream, Detector, AnyWebReadableByteStreamWithFileType} from './core.js';
|
|
7
7
|
import {FileTypeParser} from './core.js';
|
|
8
8
|
|
|
9
9
|
export type ReadableStreamWithFileType = NodeReadableStream & {
|
|
@@ -25,6 +25,7 @@ export declare class NodeFileTypeParser extends FileTypeParser {
|
|
|
25
25
|
Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor).
|
|
26
26
|
*/
|
|
27
27
|
toDetectionStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
|
|
28
|
+
toDetectionStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -64,11 +65,8 @@ Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample
|
|
|
64
65
|
The sample size impacts the file detection resolution.
|
|
65
66
|
A smaller sample size will result in lower probability of the best file type detection.
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
@param readableStream - A [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable) containing a file to examine.
|
|
71
|
-
@param options - Maybe used to override the default sample-size.
|
|
68
|
+
@param readableStream - A [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable), streaming a file to examine.
|
|
69
|
+
@param options - May be used to override the default sample size.
|
|
72
70
|
@returns A `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`.
|
|
73
71
|
|
|
74
72
|
@example
|
|
@@ -85,7 +83,8 @@ if (stream2.fileType?.mime === 'image/jpeg') {
|
|
|
85
83
|
// stream2 can be used to stream the JPEG image (from the very beginning of the stream)
|
|
86
84
|
}
|
|
87
85
|
```
|
|
88
|
-
|
|
86
|
+
*/
|
|
89
87
|
export function fileTypeStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
|
|
88
|
+
export function fileTypeStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
|
|
90
89
|
|
|
91
90
|
export * from './core.js';
|
package/index.js
CHANGED
|
@@ -3,6 +3,7 @@ Node.js specific entry point.
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {ReadableStream as WebReadableStream} from 'node:stream/web';
|
|
6
|
+
import {pipeline, PassThrough} from 'node:stream';
|
|
6
7
|
import * as strtok3 from 'strtok3';
|
|
7
8
|
import {FileTypeParser, reasonableDetectionSizeInBytes} from './core.js';
|
|
8
9
|
|
|
@@ -26,7 +27,10 @@ export class NodeFileTypeParser extends FileTypeParser {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
async toDetectionStream(readableStream, options = {}) {
|
|
29
|
-
|
|
30
|
+
if (readableStream instanceof WebReadableStream) {
|
|
31
|
+
return super.toDetectionStream(readableStream, options);
|
|
32
|
+
}
|
|
33
|
+
|
|
30
34
|
const {sampleSize = reasonableDetectionSizeInBytes} = options;
|
|
31
35
|
|
|
32
36
|
return new Promise((resolve, reject) => {
|
|
@@ -36,8 +40,8 @@ export class NodeFileTypeParser extends FileTypeParser {
|
|
|
36
40
|
(async () => {
|
|
37
41
|
try {
|
|
38
42
|
// Set up output stream
|
|
39
|
-
const pass = new
|
|
40
|
-
const outputStream =
|
|
43
|
+
const pass = new PassThrough();
|
|
44
|
+
const outputStream = pipeline ? pipeline(readableStream, pass, () => {}) : readableStream.pipe(pass);
|
|
41
45
|
|
|
42
46
|
// Read the input stream and detect the filetype
|
|
43
47
|
const chunk = readableStream.read(sampleSize) ?? readableStream.read() ?? new Uint8Array(0);
|
|
@@ -70,7 +74,7 @@ export async function fileTypeFromStream(stream, fileTypeOptions) {
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
export async function fileTypeStream(readableStream, options = {}) {
|
|
73
|
-
return new NodeFileTypeParser().toDetectionStream(readableStream, options);
|
|
77
|
+
return new NodeFileTypeParser(options).toDetectionStream(readableStream, options);
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
export {fileTypeFromTokenizer, fileTypeFromBuffer, fileTypeFromBlob, FileTypeParser, supportedMimeTypes, supportedExtensions} from './core.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "file-type",
|
|
3
|
-
"version": "19.
|
|
4
|
-
"description": "Detect the file type of a
|
|
3
|
+
"version": "19.4.0",
|
|
4
|
+
"description": "Detect the file type of a file, stream, or data",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/file-type",
|
|
7
7
|
"funding": "https://github.com/sindresorhus/file-type?sponsor=1",
|
|
@@ -13,10 +13,19 @@
|
|
|
13
13
|
"type": "module",
|
|
14
14
|
"exports": {
|
|
15
15
|
".": {
|
|
16
|
-
"node":
|
|
17
|
-
|
|
16
|
+
"node": {
|
|
17
|
+
"types": "./index.d.ts",
|
|
18
|
+
"import": "./index.js"
|
|
19
|
+
},
|
|
20
|
+
"default": {
|
|
21
|
+
"types": "./core.d.ts",
|
|
22
|
+
"import": "./core.js"
|
|
23
|
+
}
|
|
18
24
|
},
|
|
19
|
-
"./core":
|
|
25
|
+
"./core": {
|
|
26
|
+
"types": "./core.d.ts",
|
|
27
|
+
"import": "./core.js"
|
|
28
|
+
}
|
|
20
29
|
},
|
|
21
30
|
"sideEffects": false,
|
|
22
31
|
"engines": {
|
|
@@ -209,6 +218,7 @@
|
|
|
209
218
|
"vsdx"
|
|
210
219
|
],
|
|
211
220
|
"dependencies": {
|
|
221
|
+
"get-stream": "^9.0.1",
|
|
212
222
|
"strtok3": "^8.0.0",
|
|
213
223
|
"token-types": "^6.0.0",
|
|
214
224
|
"uint8array-extras": "^1.3.0"
|
package/readme.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center" title="file-type">
|
|
2
|
+
<img src="media/logo.jpg" alt="file-type logo">
|
|
3
|
+
</h1>
|
|
2
4
|
|
|
3
|
-
> Detect the file type of a
|
|
5
|
+
> Detect the file type of a file, stream, or data
|
|
4
6
|
|
|
5
7
|
The file type is detected by checking the [magic number](https://en.wikipedia.org/wiki/Magic_number_(programming)#Magic_numbers_in_files) of the buffer.
|
|
6
8
|
|
|
@@ -168,7 +170,7 @@ Or `undefined` when there is no match.
|
|
|
168
170
|
|
|
169
171
|
#### stream
|
|
170
172
|
|
|
171
|
-
Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable)
|
|
173
|
+
Type: [Web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) or [Node.js `stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable)
|
|
172
174
|
|
|
173
175
|
A readable stream representing file data.
|
|
174
176
|
|
|
@@ -265,7 +267,7 @@ Type: [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer)
|
|
|
265
267
|
|
|
266
268
|
A file source implementing the [tokenizer interface](https://github.com/Borewit/strtok3#tokenizer).
|
|
267
269
|
|
|
268
|
-
### fileTypeStream(
|
|
270
|
+
### fileTypeStream(webStream, options?)
|
|
269
271
|
|
|
270
272
|
Returns a `Promise` which resolves to the original readable stream argument, but with an added `fileType` property, which is an object like the one returned from `fileTypeFromFile()`.
|
|
271
273
|
|
|
@@ -274,8 +276,7 @@ Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample
|
|
|
274
276
|
The sample size impacts the file detection resolution.
|
|
275
277
|
A smaller sample size will result in lower probability of the best file type detection.
|
|
276
278
|
|
|
277
|
-
**Note:**
|
|
278
|
-
**Note:** Requires Node.js 14 or later.
|
|
279
|
+
**Note:** When using Node.js, a `stream.Readable` may be provided as well.
|
|
279
280
|
|
|
280
281
|
#### readableStream
|
|
281
282
|
|