file-type 8.1.0 → 9.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.js +59 -39
- package/package.json +1 -1
- package/readme.md +2 -1
package/index.js
CHANGED
|
@@ -151,41 +151,54 @@ module.exports = input => {
|
|
|
151
151
|
};
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
//
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
154
|
+
// The docx, xlsx and pptx file types extend the Office Open XML file format:
|
|
155
|
+
// https://en.wikipedia.org/wiki/Office_Open_XML_file_formats
|
|
156
|
+
// We look for:
|
|
157
|
+
// - one entry named '[Content_Types].xml' or '_rels/.rels',
|
|
158
|
+
// - one entry indicating specific type of file.
|
|
159
|
+
// MS Office, OpenOffice and LibreOffice may put the parts in different order, so the check should not rely on it.
|
|
160
|
+
const findNextZipHeaderIndex = (arr, startAt = 0) => arr.findIndex((el, i, arr) => i >= startAt && arr[i] === 0x50 && arr[i + 1] === 0x4B && arr[i + 2] === 0x3 && arr[i + 3] === 0x4);
|
|
161
|
+
|
|
162
|
+
let zipHeaderIndex = 0; // The first zip header was already found at index 0
|
|
163
|
+
let oxmlFound = false;
|
|
164
|
+
let type = null;
|
|
165
|
+
|
|
166
|
+
do {
|
|
167
|
+
const offset = zipHeaderIndex + 30;
|
|
168
|
+
|
|
169
|
+
if (!oxmlFound) {
|
|
170
|
+
oxmlFound = (check(oxmlContentTypes, {offset}) || check(oxmlRels, {offset}));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (!type) {
|
|
174
|
+
if (checkString('word/', {offset})) {
|
|
175
|
+
type = {
|
|
176
|
+
ext: 'docx',
|
|
177
|
+
mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
178
|
+
};
|
|
179
|
+
} else if (checkString('ppt/', {offset})) {
|
|
180
|
+
type = {
|
|
181
|
+
ext: 'pptx',
|
|
182
|
+
mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
183
|
+
};
|
|
184
|
+
} else if (checkString('xl/', {offset})) {
|
|
185
|
+
type = {
|
|
186
|
+
ext: 'xlsx',
|
|
187
|
+
mime: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
188
|
+
};
|
|
187
189
|
}
|
|
188
190
|
}
|
|
191
|
+
|
|
192
|
+
if (oxmlFound && type) {
|
|
193
|
+
return type;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
zipHeaderIndex = findNextZipHeaderIndex(buf, offset);
|
|
197
|
+
} while (zipHeaderIndex >= 0);
|
|
198
|
+
|
|
199
|
+
// No more zip parts available in the buffer, but maybe we are almost certain about the type?
|
|
200
|
+
if (type) {
|
|
201
|
+
return type;
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
204
|
|
|
@@ -312,13 +325,13 @@ module.exports = input => {
|
|
|
312
325
|
if (check([0x41, 0x56, 0x49], {offset: 8})) {
|
|
313
326
|
return {
|
|
314
327
|
ext: 'avi',
|
|
315
|
-
mime: 'video/
|
|
328
|
+
mime: 'video/vnd.avi'
|
|
316
329
|
};
|
|
317
330
|
}
|
|
318
331
|
if (check([0x57, 0x41, 0x56, 0x45], {offset: 8})) {
|
|
319
332
|
return {
|
|
320
333
|
ext: 'wav',
|
|
321
|
-
mime: 'audio/
|
|
334
|
+
mime: 'audio/vnd.wave'
|
|
322
335
|
};
|
|
323
336
|
}
|
|
324
337
|
// QLCM, QCP file
|
|
@@ -398,9 +411,9 @@ module.exports = input => {
|
|
|
398
411
|
check([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41], {offset: 4}) ||
|
|
399
412
|
check([0x4D, 0x34, 0x41, 0x20])
|
|
400
413
|
) {
|
|
401
|
-
return {
|
|
414
|
+
return { // MPEG-4 layer 3 (audio)
|
|
402
415
|
ext: 'm4a',
|
|
403
|
-
mime: 'audio/
|
|
416
|
+
mime: 'audio/mp4' // RFC 4337
|
|
404
417
|
};
|
|
405
418
|
}
|
|
406
419
|
|
|
@@ -468,13 +481,20 @@ module.exports = input => {
|
|
|
468
481
|
};
|
|
469
482
|
}
|
|
470
483
|
|
|
471
|
-
if (check([0x4D, 0x41, 0x43, 0x20])) {
|
|
484
|
+
if (check([0x4D, 0x41, 0x43, 0x20])) { // 'MAC '
|
|
472
485
|
return {
|
|
473
486
|
ext: 'ape',
|
|
474
487
|
mime: 'audio/ape'
|
|
475
488
|
};
|
|
476
489
|
}
|
|
477
490
|
|
|
491
|
+
if (check([0x77, 0x76, 0x70, 0x6B])) { // 'wvpk'
|
|
492
|
+
return {
|
|
493
|
+
ext: 'wv',
|
|
494
|
+
mime: 'audio/wavpack'
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
|
|
478
498
|
if (check([0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A])) {
|
|
479
499
|
return {
|
|
480
500
|
ext: 'amr',
|
|
@@ -556,7 +576,7 @@ module.exports = input => {
|
|
|
556
576
|
) {
|
|
557
577
|
return {
|
|
558
578
|
ext: 'eot',
|
|
559
|
-
mime: 'application/
|
|
579
|
+
mime: 'application/vnd.ms-fontobject'
|
|
560
580
|
};
|
|
561
581
|
}
|
|
562
582
|
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -76,7 +76,7 @@ Or `null` when no match.
|
|
|
76
76
|
|
|
77
77
|
Type: `Buffer` `Uint8Array`
|
|
78
78
|
|
|
79
|
-
It only needs the first 4100 bytes.
|
|
79
|
+
It only needs the first 4100 bytes. The exception is detection of `docx`, `pptx`, and `xlsx` which potentially requires reading the whole file.
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
## Supported file types
|
|
@@ -164,6 +164,7 @@ It only needs the first 4100 bytes.
|
|
|
164
164
|
- [`cur`](https://en.wikipedia.org/wiki/ICO_(file_format))
|
|
165
165
|
- [`ktx`](https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/)
|
|
166
166
|
- [`ape`](https://en.wikipedia.org/wiki/Monkey%27s_Audio) - Monkey's Audio
|
|
167
|
+
- [`wv`](https://en.wikipedia.org/wiki/WavPack) - WavPack
|
|
167
168
|
|
|
168
169
|
*SVG isn't included as it requires the whole file to be read, but you can get it [here](https://github.com/sindresorhus/is-svg).*
|
|
169
170
|
|