file-type 17.1.4 → 18.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/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {Readable as ReadableStream} from 'node:stream';
2
- import {ITokenizer} from 'strtok3/lib/core';
2
+ import {ITokenizer} from 'strtok3';
3
3
 
4
4
  export type FileExtension =
5
5
  | 'jpg'
@@ -364,7 +364,7 @@ export interface StreamOptions {
364
364
  }
365
365
 
366
366
  /**
367
- 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()`.
367
+ 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()`.
368
368
 
369
369
  This method can be handy to put in between a stream, but it comes with a price.
370
370
  Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type.
@@ -375,7 +375,7 @@ A smaller sample size will result in lower probability of the best file type det
375
375
  **Note:** Requires Node.js 14 or later.
376
376
 
377
377
  @param readableStream - A [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable) containing a file to examine.
378
- @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()`.
378
+ @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()`.
379
379
 
380
380
  @example
381
381
  ```
@@ -387,7 +387,7 @@ const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
387
387
  const stream1 = got.stream(url);
388
388
  const stream2 = await fileTypeStream(stream1, {sampleSize: 1024});
389
389
 
390
- if (stream2.fileType && stream2.fileType.mime === 'image/jpeg') {
390
+ if (stream2.fileType?.mime === 'image/jpeg') {
391
391
  // stream2 can be used to stream the JPEG image (from the very beginning of the stream)
392
392
  }
393
393
  ```
package/core.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {Buffer} from 'node:buffer';
2
2
  import * as Token from 'token-types';
3
- import * as strtok3 from 'strtok3/core';
3
+ import * as strtok3 from 'strtok3/core'; // eslint-disable-line n/file-extension-in-import
4
4
  import {
5
5
  stringToBytes,
6
6
  tarHeaderChecksumMatches,
@@ -26,7 +26,7 @@ export async function fileTypeFromBuffer(input) {
26
26
 
27
27
  const buffer = input instanceof Uint8Array ? input : new Uint8Array(input);
28
28
 
29
- if (!(buffer && buffer.length > 1)) {
29
+ if (!(buffer?.length > 1)) {
30
30
  return;
31
31
  }
32
32
 
@@ -146,6 +146,12 @@ class FileTypeParser {
146
146
 
147
147
  // -- 3-byte signatures --
148
148
 
149
+ if (this.check([0xEF, 0xBB, 0xBF])) { // UTF-8-BOM
150
+ // Strip off UTF-8-BOM
151
+ this.tokenizer.ignore(3);
152
+ return this.parse(tokenizer);
153
+ }
154
+
149
155
  if (this.check([0x47, 0x49, 0x46])) {
150
156
  return {
151
157
  ext: 'gif',
@@ -331,7 +337,8 @@ class FileTypeParser {
331
337
  // - one entry indicating specific type of file.
332
338
  // MS Office, OpenOffice and LibreOffice may put the parts in different order, so the check should not rely on it.
333
339
  if (zipHeader.filename === 'mimetype' && zipHeader.compressedSize === zipHeader.uncompressedSize) {
334
- const mimeType = (await tokenizer.readToken(new Token.StringType(zipHeader.compressedSize, 'utf-8'))).trim();
340
+ let mimeType = await tokenizer.readToken(new Token.StringType(zipHeader.compressedSize, 'utf-8'));
341
+ mimeType = mimeType.trim();
335
342
 
336
343
  switch (mimeType) {
337
344
  case 'application/epub+zip':
@@ -1016,13 +1023,6 @@ class FileTypeParser {
1016
1023
  };
1017
1024
  }
1018
1025
 
1019
- if (this.check([0xEF, 0xBB, 0xBF]) && this.checkString('<?xml', {offset: 3})) { // UTF-8-BOM
1020
- return {
1021
- ext: 'xml',
1022
- mime: 'application/xml',
1023
- };
1024
- }
1025
-
1026
1026
  // -- 9-byte signatures --
1027
1027
 
1028
1028
  if (this.check([0x49, 0x49, 0x52, 0x4F, 0x08, 0x00, 0x00, 0x00, 0x18])) {
@@ -1160,14 +1160,15 @@ class FileTypeParser {
1160
1160
  };
1161
1161
  }
1162
1162
 
1163
- if (
1164
- this.check([0xFE, 0xFF, 0, 60, 0, 63, 0, 120, 0, 109, 0, 108]) // UTF-16-BOM-LE
1165
- || this.check([0xFF, 0xFE, 60, 0, 63, 0, 120, 0, 109, 0, 108, 0]) // UTF-16-BOM-LE
1166
- ) {
1167
- return {
1168
- ext: 'xml',
1169
- mime: 'application/xml',
1170
- };
1163
+ if (this.check([0xFE, 0xFF])) { // UTF-16-BOM-LE
1164
+ if (this.check([0, 60, 0, 63, 0, 120, 0, 109, 0, 108], {offset: 2})) {
1165
+ return {
1166
+ ext: 'xml',
1167
+ mime: 'application/xml',
1168
+ };
1169
+ }
1170
+
1171
+ return undefined; // Some unknown text based format
1171
1172
  }
1172
1173
 
1173
1174
  // -- Unsafe signatures --
@@ -1361,11 +1362,22 @@ class FileTypeParser {
1361
1362
  };
1362
1363
  }
1363
1364
 
1364
- if (this.check([0xFF, 0xFE, 0xFF, 0x0E, 0x53, 0x00, 0x6B, 0x00, 0x65, 0x00, 0x74, 0x00, 0x63, 0x00, 0x68, 0x00, 0x55, 0x00, 0x70, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6C, 0x00])) {
1365
- return {
1366
- ext: 'skp',
1367
- mime: 'application/vnd.sketchup.skp',
1368
- };
1365
+ if (this.check([0xFF, 0xFE])) { // UTF-16-BOM-BE
1366
+ if (this.check([60, 0, 63, 0, 120, 0, 109, 0, 108, 0], {offset: 2})) {
1367
+ return {
1368
+ ext: 'xml',
1369
+ mime: 'application/xml',
1370
+ };
1371
+ }
1372
+
1373
+ if (this.check([0xFF, 0x0E, 0x53, 0x00, 0x6B, 0x00, 0x65, 0x00, 0x74, 0x00, 0x63, 0x00, 0x68, 0x00, 0x55, 0x00, 0x70, 0x00, 0x20, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6C, 0x00], {offset: 2})) {
1374
+ return {
1375
+ ext: 'skp',
1376
+ mime: 'application/vnd.sketchup.skp',
1377
+ };
1378
+ }
1379
+
1380
+ return undefined; // Some text based format
1369
1381
  }
1370
1382
 
1371
1383
  if (this.checkString('-----BEGIN PGP MESSAGE-----')) {
@@ -1488,7 +1500,6 @@ class FileTypeParser {
1488
1500
  }
1489
1501
 
1490
1502
  export async function fileTypeStream(readableStream, {sampleSize = minimumBytes} = {}) {
1491
- // eslint-disable-next-line node/no-unsupported-features/es-syntax
1492
1503
  const {default: stream} = await import('node:stream');
1493
1504
 
1494
1505
  return new Promise((resolve, reject) => {
@@ -1502,7 +1513,7 @@ export async function fileTypeStream(readableStream, {sampleSize = minimumBytes}
1502
1513
  const outputStream = stream.pipeline ? stream.pipeline(readableStream, pass, () => {}) : readableStream.pipe(pass);
1503
1514
 
1504
1515
  // Read the input stream and detect the filetype
1505
- const chunk = readableStream.read(sampleSize) || readableStream.read() || Buffer.alloc(0);
1516
+ const chunk = readableStream.read(sampleSize) ?? readableStream.read() ?? Buffer.alloc(0);
1506
1517
  try {
1507
1518
  const fileType = await fileTypeFromBuffer(chunk);
1508
1519
  pass.fileType = fileType;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-type",
3
- "version": "17.1.4",
3
+ "version": "18.0.0",
4
4
  "description": "Detect the file type of a Buffer/Uint8Array/ArrayBuffer",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/file-type",
@@ -19,7 +19,7 @@
19
19
  "./core": "./core.js"
20
20
  },
21
21
  "engines": {
22
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
22
+ "node": ">=14.16"
23
23
  },
24
24
  "scripts": {
25
25
  "test": "xo && ava && tsd"
@@ -197,18 +197,17 @@
197
197
  ],
198
198
  "dependencies": {
199
199
  "readable-web-to-node-stream": "^3.0.2",
200
- "strtok3": "^7.0.0-alpha.9",
201
- "token-types": "^5.0.0-alpha.2"
200
+ "strtok3": "^7.0.0",
201
+ "token-types": "^5.0.1"
202
202
  },
203
203
  "devDependencies": {
204
204
  "@tokenizer/token": "^0.3.0",
205
- "@types/node": "^16.11.10",
206
- "ava": "^3.15.0",
205
+ "@types/node": "^18.7.13",
206
+ "ava": "^4.3.1",
207
207
  "commonmark": "^0.30.0",
208
208
  "noop-stream": "^1.0.0",
209
- "tsd": "^0.19.0",
210
- "typescript": "^4.5.2",
211
- "xo": "^0.46.4"
209
+ "tsd": "^0.22.0",
210
+ "xo": "^0.51.0"
212
211
  },
213
212
  "xo": {
214
213
  "envs": [
@@ -219,11 +218,11 @@
219
218
  "no-inner-declarations": "warn",
220
219
  "no-await-in-loop": "warn",
221
220
  "no-bitwise": "off",
222
- "@typescript-eslint/no-unsafe-assignment": "off"
221
+ "@typescript-eslint/no-unsafe-assignment": "off",
222
+ "unicorn/text-encoding-identifier-case": "off"
223
223
  }
224
224
  },
225
225
  "ava": {
226
- "serial": true,
227
- "verbose": true
226
+ "serial": true
228
227
  }
229
228
  }
package/readme.md CHANGED
@@ -141,7 +141,7 @@ Detect the file type of a `Buffer`, `Uint8Array`, or `ArrayBuffer`.
141
141
 
142
142
  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.
143
143
 
144
- If file access is available, it is recommended to use `FileType.fromFile()` instead.
144
+ If file access is available, it is recommended to use `fileTypeFromFile()` instead.
145
145
 
146
146
  Returns a `Promise` for an object with the detected file type and MIME type:
147
147
 
@@ -282,7 +282,7 @@ A file source implementing the [tokenizer interface](https://github.com/Borewit/
282
282
 
283
283
  ### fileTypeStream(readableStream, options?)
284
284
 
285
- 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()`.
285
+ 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()`.
286
286
 
287
287
  This method can be handy to put in between a stream, but it comes with a price.
288
288
  Internally `stream()` builds up a buffer of `sampleSize` bytes, used as a sample, to determine the file type.
@@ -318,7 +318,7 @@ const url = 'https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg';
318
318
  const stream1 = got.stream(url);
319
319
  const stream2 = await fileTypeStream(stream1, {sampleSize: 1024});
320
320
 
321
- if (stream2.fileType && stream2.fileType.mime === 'image/jpeg') {
321
+ if (stream2.fileType?.mime === 'image/jpeg') {
322
322
  // stream2 can be used to stream the JPEG image (from the very beginning of the stream)
323
323
  }
324
324
  ```
package/util.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export function stringToBytes(string) {
2
- return [...string].map(character => character.charCodeAt(0));
2
+ return [...string].map(character => character.charCodeAt(0)); // eslint-disable-line unicorn/prefer-code-point
3
3
  }
4
4
 
5
5
  /**
@@ -17,12 +17,12 @@ export function tarHeaderChecksumMatches(buffer, offset = 0) {
17
17
 
18
18
  let sum = 8 * 0x20; // Initialize signed bit sum
19
19
 
20
- for (let i = offset; i < offset + 148; i++) {
21
- sum += buffer[i];
20
+ for (let index = offset; index < offset + 148; index++) {
21
+ sum += buffer[index];
22
22
  }
23
23
 
24
- for (let i = offset + 156; i < offset + 512; i++) {
25
- sum += buffer[i];
24
+ for (let index = offset + 156; index < offset + 512; index++) {
25
+ sum += buffer[index];
26
26
  }
27
27
 
28
28
  return readSum === sum;