file-type 16.5.0 → 17.0.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/index.d.ts CHANGED
@@ -1,11 +1,5 @@
1
- /// <reference types="node"/>
2
- import {Readable as ReadableStream} from 'stream';
3
- import * as core from './core';
4
-
5
- export type ReadableStreamWithFileType = core.ReadableStreamWithFileType;
6
- export type FileTypeResult = core.FileTypeResult;
7
- export type FileExtension = core.FileExtension;
8
- export type MimeType = core.MimeType;
1
+ import {Readable as ReadableStream} from 'node:stream';
2
+ import {FileTypeResult} from './core.js';
9
3
 
10
4
  /**
11
5
  Detect the file type of a file path.
@@ -15,13 +9,6 @@ The file type is detected by checking the [magic number](https://en.wikipedia.or
15
9
  @param path - The file path to parse.
16
10
  @returns The detected file type and MIME type or `undefined` when there is no match.
17
11
  */
18
- export function fromFile(path: string): Promise<core.FileTypeResult | undefined>;
12
+ export function fileTypeFromFile(path: string): Promise<FileTypeResult | undefined>;
19
13
 
20
- export {
21
- fromBuffer,
22
- fromStream,
23
- fromTokenizer,
24
- extensions,
25
- mimeTypes,
26
- stream
27
- } from './core';
14
+ export * from './core.js';
package/index.js CHANGED
@@ -1,32 +1,13 @@
1
- 'use strict';
2
- const strtok3 = require('strtok3');
3
- const core = require('./core');
1
+ import * as strtok3 from 'strtok3';
2
+ import {fileTypeFromTokenizer} from './core.js';
4
3
 
5
- async function fromFile(path) {
4
+ export async function fileTypeFromFile(path) {
6
5
  const tokenizer = await strtok3.fromFile(path);
7
6
  try {
8
- return await core.fromTokenizer(tokenizer);
7
+ return await fileTypeFromTokenizer(tokenizer);
9
8
  } finally {
10
9
  await tokenizer.close();
11
10
  }
12
11
  }
13
12
 
14
- const fileType = {
15
- fromFile
16
- };
17
-
18
- Object.assign(fileType, core);
19
-
20
- Object.defineProperty(fileType, 'extensions', {
21
- get() {
22
- return core.extensions;
23
- }
24
- });
25
-
26
- Object.defineProperty(fileType, 'mimeTypes', {
27
- get() {
28
- return core.mimeTypes;
29
- }
30
- });
31
-
32
- module.exports = fileType;
13
+ export * from './core.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-type",
3
- "version": "16.5.0",
3
+ "version": "17.0.0",
4
4
  "description": "Detect the file type of a Buffer/Uint8Array/ArrayBuffer",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/file-type",
@@ -10,11 +10,18 @@
10
10
  "email": "sindresorhus@gmail.com",
11
11
  "url": "https://sindresorhus.com"
12
12
  },
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "node": "./index.js",
17
+ "default": "./browser.js"
18
+ },
19
+ "./core": "./core.js"
20
+ },
13
21
  "engines": {
14
- "node": ">=8"
22
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
15
23
  },
16
24
  "scripts": {
17
- "ava": "ava --serial --verbose",
18
25
  "test": "xo && ava && tsd"
19
26
  },
20
27
  "files": [
@@ -187,18 +194,19 @@
187
194
  "jxl",
188
195
  "vcf"
189
196
  ],
190
- "devDependencies": {
191
- "@types/node": "^13.1.4",
192
- "ava": "^2.3.0",
193
- "noop-stream": "^0.1.0",
194
- "read-chunk": "^3.2.0",
195
- "tsd": "^0.11.0",
196
- "xo": "^0.25.3"
197
- },
198
197
  "dependencies": {
199
- "readable-web-to-node-stream": "^3.0.0",
200
- "strtok3": "^6.0.3",
201
- "token-types": "^2.0.0"
198
+ "readable-web-to-node-stream": "^3.0.2",
199
+ "strtok3": "7.0.0-alpha.4",
200
+ "token-types": "^4.1.1"
201
+ },
202
+ "devDependencies": {
203
+ "@tokenizer/token": "^0.3.0",
204
+ "@types/node": "^16.11.10",
205
+ "ava": "^3.15.0",
206
+ "noop-stream": "^1.0.0",
207
+ "tsd": "^0.19.0",
208
+ "typescript": "^4.5.2",
209
+ "xo": "^0.46.4"
202
210
  },
203
211
  "xo": {
204
212
  "envs": [
@@ -208,8 +216,12 @@
208
216
  "rules": {
209
217
  "no-inner-declarations": "warn",
210
218
  "no-await-in-loop": "warn",
211
- "promise/prefer-await-to-then": "warn",
212
- "prefer-named-capture-group": "off"
219
+ "no-bitwise": "off",
220
+ "@typescript-eslint/no-unsafe-assignment": "off"
213
221
  }
222
+ },
223
+ "ava": {
224
+ "serial": true,
225
+ "verbose": true
214
226
  }
215
227
  }
package/readme.md CHANGED
@@ -6,10 +6,40 @@ The file type is detected by checking the [magic number](https://en.wikipedia.or
6
6
 
7
7
  This package is for detecting binary-based file formats, not text-based formats like `.txt`, `.csv`, `.svg`, etc.
8
8
 
9
+ <br>
10
+
11
+ ---
12
+
13
+ <div align="center">
14
+ <p>
15
+ <p>
16
+ <sup>
17
+ <a href="https://github.com/sponsors/sindresorhus">My open source work is supported by the community</a>
18
+ </sup>
19
+ </p>
20
+ <sup>Special thanks to:</sup>
21
+ <br>
22
+ <br>
23
+ <a href="https://bit.io/?utm_campaign=github_repo&utm_medium=referral&utm_content=file-type&utm_source=github">
24
+ <div>
25
+ <img src="https://sindresorhus.com/assets/thanks/bitio-logo.svg" width="190" alt="bit.io">
26
+ </div>
27
+ <b>Instant, shareable cloud PostgreSQL database</b>
28
+ <div>
29
+ <sup>Import any dataset in seconds, share with anyone with a click, try without signing up</sup>
30
+ </div>
31
+ </a>
32
+ </p>
33
+ </div>
34
+
35
+ ---
36
+
37
+ <br>
38
+
9
39
  ## Install
10
40
 
11
- ```
12
- $ npm install file-type
41
+ ```sh
42
+ npm install file-type
13
43
  ```
14
44
 
15
45
  ## Usage
@@ -19,114 +49,99 @@ $ npm install file-type
19
49
  Determine file type from a file:
20
50
 
21
51
  ```js
22
- const FileType = require('file-type');
52
+ import {fileTypeFromFile} from 'file-type';
23
53
 
24
- (async () => {
25
- console.log(await FileType.fromFile('Unicorn.png'));
26
- //=> {ext: 'png', mime: 'image/png'}
27
- })();
54
+ console.log(await fileTypeFromFile('Unicorn.png'));
55
+ //=> {ext: 'png', mime: 'image/png'}
28
56
  ```
29
57
 
30
58
  Determine file type from a Buffer, which may be a portion of the beginning of a file:
31
59
 
32
60
  ```js
33
- const FileType = require('file-type');
34
- const readChunk = require('read-chunk');
61
+ import {fileTypeFromBuffer} from 'file-type';
62
+ import {readChunk} from 'read-chunk';
35
63
 
36
- (async () => {
37
- const buffer = readChunk.sync('Unicorn.png', 0, 4100);
64
+ const buffer = await readChunk('Unicorn.png', {length: 4100});
38
65
 
39
- console.log(await FileType.fromBuffer(buffer));
40
- //=> {ext: 'png', mime: 'image/png'}
41
- })();
66
+ console.log(await fileTypeFromBuffer(buffer));
67
+ //=> {ext: 'png', mime: 'image/png'}
42
68
  ```
43
69
 
44
70
  Determine file type from a stream:
45
71
 
46
72
  ```js
47
- const fs = require('fs');
48
- const FileType = require('file-type');
73
+ import fs from 'node:fs';
74
+ import {fileTypeFromStream} from 'file-type';
49
75
 
50
- (async () => {
51
- const stream = fs.createReadStream('Unicorn.mp4');
76
+ const stream = fs.createReadStream('Unicorn.mp4');
52
77
 
53
- console.log(await FileType.fromStream(stream));
54
- //=> {ext: 'mp4', mime: 'video/mp4'}
55
- }
56
- )();
78
+ console.log(await fileTypeFromStream(stream));
79
+ //=> {ext: 'mp4', mime: 'video/mp4'}
57
80
  ```
58
81
 
59
82
  The stream method can also be used to read from a remote location:
60
83
 
61
84
  ```js
62
- const got = require('got');
63
- const FileType = require('file-type');
85
+ import got from 'got';
86
+ import {fileTypeFromStream} from 'file-type';
64
87
 
65
88
  const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
66
89
 
67
- (async () => {
68
- const stream = got.stream(url);
90
+ const stream = got.stream(url);
69
91
 
70
- console.log(await FileType.fromStream(stream));
71
- //=> {ext: 'jpg', mime: 'image/jpeg'}
72
- })();
92
+ console.log(await fileTypeFromStream(stream));
93
+ //=> {ext: 'jpg', mime: 'image/jpeg'}
73
94
  ```
74
95
 
75
96
  Another stream example:
76
97
 
77
98
  ```js
78
- const stream = require('stream');
79
- const fs = require('fs');
80
- const crypto = require('crypto');
81
- const FileType = require('file-type');
99
+ import stream from 'node:stream';
100
+ import fs from 'node:fs';
101
+ import crypto from 'node:crypto';
102
+ import {fileTypeStream} from 'file-type';
82
103
 
83
- (async () => {
84
- const read = fs.createReadStream('encrypted.enc');
85
- const decipher = crypto.createDecipheriv(alg, key, iv);
104
+ const read = fs.createReadStream('encrypted.enc');
105
+ const decipher = crypto.createDecipheriv(alg, key, iv);
86
106
 
87
- const fileTypeStream = await FileType.stream(stream.pipeline(read, decipher));
107
+ const streamWithFileType = await fileTypeStream(stream.pipeline(read, decipher));
88
108
 
89
- console.log(fileTypeStream.fileType);
90
- //=> {ext: 'mov', mime: 'video/quicktime'}
109
+ console.log(streamWithFileType.fileType);
110
+ //=> {ext: 'mov', mime: 'video/quicktime'}
91
111
 
92
- const write = fs.createWriteStream(`decrypted.${fileTypeStream.fileType.ext}`);
93
- fileTypeStream.pipe(write);
94
- })();
112
+ const write = fs.createWriteStream(`decrypted.${streamWithFileType.fileType.ext}`);
113
+ streamWithFileType.pipe(write);
95
114
  ```
96
115
 
97
116
  #### Browser
98
117
 
99
118
  ```js
100
- const FileType = require('file-type/browser');
119
+ import {fileTypeFromStream} from 'file-type';
101
120
 
102
121
  const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
103
122
 
104
- (async () => {
105
- const response = await fetch(url);
106
- const fileType = await FileType.fromStream(response.body);
123
+ const response = await fetch(url);
124
+ const fileType = await fileTypeFromStream(response.body);
107
125
 
108
- console.log(fileType);
109
- //=> {ext: 'jpg', mime: 'image/jpeg'}
110
- })();
126
+ console.log(fileType);
127
+ //=> {ext: 'jpg', mime: 'image/jpeg'}
111
128
  ```
112
129
 
113
130
  ```js
114
- const FileType = require('file-type/browser');
131
+ import {fileTypeFromBlob} from 'file-type';
115
132
 
116
- (async () => {
117
- const blob = new Blob(['<?xml version="1.0" encoding="ISO-8859-1" ?>'], {
118
- type: 'plain/text',
119
- endings: 'native'
120
- });
133
+ const blob = new Blob(['<?xml version="1.0" encoding="ISO-8859-1" ?>'], {
134
+ type: 'plain/text',
135
+ endings: 'native'
136
+ });
121
137
 
122
- console.log(await FileType.fromBlob(blob));
123
- //=> {ext: 'txt', mime: 'plain/text'}
124
- })();
138
+ console.log(await fileTypeFromBlob(blob));
139
+ //=> {ext: 'txt', mime: 'plain/text'}
125
140
  ```
126
141
 
127
142
  ## API
128
143
 
129
- ### FileType.fromBuffer(buffer)
144
+ ### fileTypeFromBuffer(buffer)
130
145
 
131
146
  Detect the file type of a `Buffer`, `Uint8Array`, or `ArrayBuffer`.
132
147
 
@@ -147,7 +162,7 @@ Type: `Buffer | Uint8Array | ArrayBuffer`
147
162
 
148
163
  A buffer representing file data. It works best if the buffer contains the entire file, it may work with a smaller portion as well.
149
164
 
150
- ### FileType.fromFile(filePath)
165
+ ### fileTypeFromFile(filePath)
151
166
 
152
167
  Detect the file type of a file path.
153
168
 
@@ -166,7 +181,7 @@ Type: `string`
166
181
 
167
182
  The file path to parse.
168
183
 
169
- ### FileType.fromStream(stream)
184
+ ### fileTypeFromStream(stream)
170
185
 
171
186
  Detect the file type of a Node.js [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable).
172
187
 
@@ -185,7 +200,7 @@ Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream
185
200
 
186
201
  A readable stream representing file data.
187
202
 
188
- ### FileType.fromTokenizer(tokenizer)
203
+ ### fileTypeFromTokenizer(tokenizer)
189
204
 
190
205
  Detect the file type from an `ITokenizer` source.
191
206
 
@@ -203,41 +218,37 @@ Or `undefined` when there is no match.
203
218
  An example is [`@tokenizer/http`](https://github.com/Borewit/tokenizer-http), which requests data using [HTTP-range-requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests). A difference with a conventional stream and the [*tokenizer*](https://github.com/Borewit/strtok3#tokenizer), is that it can *ignore* (seek, fast-forward) in the stream. For example, you may only need and read the first 6 bytes, and the last 128 bytes, which may be an advantage in case reading the entire file would take longer.
204
219
 
205
220
  ```js
206
- const {makeTokenizer} = require('@tokenizer/http');
207
- const FileType = require('file-type');
221
+ import {makeTokenizer} from '@tokenizer/http';
222
+ import {fileTypeFromTokenizer} from 'file-type';
208
223
 
209
224
  const audioTrackUrl = 'https://test-audio.netlify.com/Various%20Artists%20-%202009%20-%20netBloc%20Vol%2024_%20tiuqottigeloot%20%5BMP3-V2%5D/01%20-%20Diablo%20Swing%20Orchestra%20-%20Heroines.mp3';
210
225
 
211
- (async () => {
212
- const httpTokenizer = await makeTokenizer(audioTrackUrl);
213
- const fileType = await FileType.fromTokenizer(httpTokenizer);
226
+ const httpTokenizer = await makeTokenizer(audioTrackUrl);
227
+ const fileType = await fileTypeFromTokenizer(httpTokenizer);
214
228
 
215
- console.log(fileType);
216
- //=> {ext: 'mp3', mime: 'audio/mpeg'}
217
- })();
229
+ console.log(fileType);
230
+ //=> {ext: 'mp3', mime: 'audio/mpeg'}
218
231
  ```
219
232
 
220
233
  Or use [`@tokenizer/s3`](https://github.com/Borewit/tokenizer-s3) to determine the file type of a file stored on [Amazon S3](https://aws.amazon.com/s3):
221
234
 
222
235
  ```js
223
- const FileType = require('file-type');
224
- const S3 = require('aws-sdk/clients/s3');
225
- const {makeTokenizer} = require('@tokenizer/s3');
226
-
227
- (async () => {
228
- // Initialize the S3 client
229
- const s3 = new S3();
230
-
231
- // Initialize the S3 tokenizer.
232
- const s3Tokenizer = await makeTokenizer(s3, {
233
- Bucket: 'affectlab',
234
- Key: '1min_35sec.mp4'
235
- });
236
-
237
- // Figure out what kind of file it is.
238
- const fileType = await FileType.fromTokenizer(s3Tokenizer);
239
- console.log(fileType);
240
- })();
236
+ import S3 from 'aws-sdk/clients/s3';
237
+ import {makeTokenizer} from '@tokenizer/s3';
238
+ import {fileTypeFromTokenizer} from 'file-type';
239
+
240
+ // Initialize the S3 client
241
+ const s3 = new S3();
242
+
243
+ // Initialize the S3 tokenizer.
244
+ const s3Tokenizer = await makeTokenizer(s3, {
245
+ Bucket: 'affectlab',
246
+ Key: '1min_35sec.mp4'
247
+ });
248
+
249
+ // Figure out what kind of file it is.
250
+ const fileType = await fileTypeFromTokenizer(s3Tokenizer);
251
+ console.log(fileType);
241
252
  ```
242
253
 
243
254
  Note that only the minimum amount of data required to determine the file type is read (okay, just a bit extra to prevent too many fragmented reads).
@@ -248,13 +259,48 @@ Type: [`ITokenizer`](https://github.com/Borewit/strtok3#tokenizer)
248
259
 
249
260
  A file source implementing the [tokenizer interface](https://github.com/Borewit/strtok3#tokenizer).
250
261
 
251
- ### FileType.stream(readableStream)
252
-
253
- Detect the file type of a readable stream.
262
+ ### fileTypeStream(readableStream, options?)
254
263
 
255
264
  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 `FileType.fromFile()`.
256
265
 
257
- *Note:* This method is only available using Node.js.
266
+ This method can be handy to put in between a stream, but it comes with a price.
267
+ Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type.
268
+ The sample size impacts the file detection resolution.
269
+ A smaller sample size will result in lower probability of the best file type detection.
270
+
271
+ **Note:** This method is only available when using Node.js.
272
+ **Note:** Requires Node.js 14 or later.
273
+
274
+ #### readableStream
275
+
276
+ Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream_readable)
277
+
278
+ #### options
279
+
280
+ Type: `object`
281
+
282
+ ##### sampleSize
283
+
284
+ Type: `number`\
285
+ Default: `4100`
286
+
287
+ The sample size in bytes.
288
+
289
+ #### Example
290
+
291
+ ```js
292
+ import got from 'got';
293
+ import {fileTypeStream} from 'file-type';
294
+
295
+ const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
296
+
297
+ const stream1 = got.stream(url);
298
+ const stream2 = await fileTypeStream(stream1, {sampleSize: 1024});
299
+
300
+ if (stream2.fileType && stream2.fileType.mime === 'image/jpeg') {
301
+ // stream2 can be used to stream the JPEG image (from the very beginning of the stream)
302
+ }
303
+ ```
258
304
 
259
305
  #### readableStream
260
306
 
@@ -262,13 +308,13 @@ Type: [`stream.Readable`](https://nodejs.org/api/stream.html#stream_class_stream
262
308
 
263
309
  The input stream.
264
310
 
265
- ### FileType.extensions
311
+ ### supportedExtensions
266
312
 
267
- Returns a set of supported file extensions.
313
+ Returns a `Set<string>` of supported file extensions.
268
314
 
269
- ### FileType.mimeTypes
315
+ ### supportedMimeTypes
270
316
 
271
- Returns a set of supported MIME types.
317
+ Returns a `Set<string>` of supported MIME types.
272
318
 
273
319
  ## Supported file types
274
320
 
@@ -349,7 +395,7 @@ Returns a set of supported MIME types.
349
395
  - [`lz`](https://en.wikipedia.org/wiki/Lzip) - Arhive file
350
396
  - [`cfb`](https://en.wikipedia.org/wiki/Compound_File_Binary_Format) - Compount File Binary Format
351
397
  - [`mxf`](https://en.wikipedia.org/wiki/Material_Exchange_Format) - Material Exchange Format
352
- - [`mts`](https://en.wikipedia.org/wiki/.m2ts) - Blu-ray Disc Audio-Video MPEG-2 Transport Stream
398
+ - [`mts`](https://en.wikipedia.org/wiki/.m2ts) - MPEG-2 Transport Stream, both raw and Blu-ray Disc Audio-Video (BDAV) versions
353
399
  - [`wasm`](https://en.wikipedia.org/wiki/WebAssembly) - WebAssembly intermediate compiled format
354
400
  - [`blend`](https://wiki.blender.org/index.php/Dev:Source/Architecture/File_Format) - Blender project
355
401
  - [`bpg`](https://bellard.org/bpg/) - Better Portable Graphics file