file-type 19.3.0 → 19.4.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.
package/core.d.ts CHANGED
@@ -3,7 +3,7 @@ Typings for primary entry point, Node.js specific typings can be found in index.
3
3
  */
4
4
 
5
5
  import type {ReadableStream as WebReadableStream} from 'node:stream/web';
6
- import type {ITokenizer} from 'strtok3';
6
+ import type {ITokenizer, AnyWebByteStream} from 'strtok3';
7
7
 
8
8
  /**
9
9
  Either the Node.js ReadableStream or the `lib.dom.d.ts` ReadableStream.
@@ -350,7 +350,7 @@ The file type is detected by checking the [magic number](https://en.wikipedia.or
350
350
  @param stream - A [web `ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) streaming a file to examine.
351
351
  @returns A `Promise` for an object with the detected file type, or `undefined` when there is no match.
352
352
  */
353
- export function fileTypeFromStream(stream: AnyWebReadableStream<Uint8Array>): Promise<FileTypeResult | undefined>;
353
+ export function fileTypeFromStream(stream: AnyWebByteStream): Promise<FileTypeResult | undefined>;
354
354
 
355
355
  /**
356
356
  Detect the file type from an [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer) source.
@@ -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, options) {
55
+ return new FileTypeParser(options).toDetectionStream(webStream, options);
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,8 @@ 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 {AnyWebByteStream} from 'strtok3';
7
+ import type {FileTypeResult, StreamOptions, AnyWebReadableStream, Detector, AnyWebReadableByteStreamWithFileType} from './core.js';
7
8
  import {FileTypeParser} from './core.js';
8
9
 
9
10
  export type ReadableStreamWithFileType = NodeReadableStream & {
@@ -25,6 +26,7 @@ export declare class NodeFileTypeParser extends FileTypeParser {
25
26
  Works the same way as {@link fileTypeStream}, additionally taking into account custom detectors (if any were provided to the constructor).
26
27
  */
27
28
  toDetectionStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
29
+ toDetectionStream(webStream: AnyWebReadableStream<Uint8Array>, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
28
30
  }
29
31
 
30
32
  /**
@@ -64,11 +66,8 @@ Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample
64
66
  The sample size impacts the file detection resolution.
65
67
  A smaller sample size will result in lower probability of the best file type detection.
66
68
 
67
- **Note:** This method is only available when using Node.js.
68
- **Note:** Requires Node.js 14 or later.
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.
69
+ @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.
70
+ @param options - May be used to override the default sample size.
72
71
  @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
72
 
74
73
  @example
@@ -85,7 +84,8 @@ if (stream2.fileType?.mime === 'image/jpeg') {
85
84
  // stream2 can be used to stream the JPEG image (from the very beginning of the stream)
86
85
  }
87
86
  ```
88
- */
87
+ */
89
88
  export function fileTypeStream(readableStream: NodeReadableStream, options?: StreamOptions): Promise<ReadableStreamWithFileType>;
89
+ export function fileTypeStream(webStream: AnyWebByteStream, options?: StreamOptions): Promise<AnyWebReadableByteStreamWithFileType>;
90
90
 
91
91
  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, Readable} 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
- const {default: stream} = await import('node:stream');
30
+ if (!(readableStream instanceof Readable)) {
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 stream.PassThrough();
40
- const outputStream = stream.pipeline ? stream.pipeline(readableStream, pass, () => {}) : readableStream.pipe(pass);
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.3.0",
4
- "description": "Detect the file type of a Uint8Array/ArrayBuffer",
3
+ "version": "19.4.1",
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": "./index.js",
17
- "default": "./core.js"
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": "./core.js"
25
+ "./core": {
26
+ "types": "./core.d.ts",
27
+ "import": "./core.js"
28
+ }
20
29
  },
21
30
  "sideEffects": false,
22
31
  "engines": {
@@ -209,7 +218,8 @@
209
218
  "vsdx"
210
219
  ],
211
220
  "dependencies": {
212
- "strtok3": "^8.0.0",
221
+ "get-stream": "^9.0.1",
222
+ "strtok3": "^8.1.0",
213
223
  "token-types": "^6.0.0",
214
224
  "uint8array-extras": "^1.3.0"
215
225
  },
package/readme.md CHANGED
@@ -1,6 +1,8 @@
1
- # file-type
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 Uint8Array/ArrayBuffer
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(readableStream, options?)
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:** This method is only available when using Node.js.
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