file-type 4.0.0 → 4.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.
Files changed (3) hide show
  1. package/index.js +158 -76
  2. package/package.json +6 -5
  3. package/readme.md +8 -5
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  'use strict';
2
+
2
3
  module.exports = input => {
3
4
  const buf = new Uint8Array(input);
4
5
 
@@ -6,137 +7,170 @@ module.exports = input => {
6
7
  return null;
7
8
  }
8
9
 
9
- if (buf[0] === 0xFF && buf[1] === 0xD8 && buf[2] === 0xFF) {
10
+ const check = (header, opts) => {
11
+ opts = Object.assign({
12
+ offset: 0
13
+ }, opts);
14
+
15
+ for (let i = 0; i < header.length; i++) {
16
+ if (header[i] !== buf[i + opts.offset]) {
17
+ return false;
18
+ }
19
+ }
20
+
21
+ return true;
22
+ };
23
+
24
+ if (check([0xFF, 0xD8, 0xFF])) {
10
25
  return {
11
26
  ext: 'jpg',
12
27
  mime: 'image/jpeg'
13
28
  };
14
29
  }
15
30
 
16
- if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4E && buf[3] === 0x47) {
31
+ if (check([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) {
17
32
  return {
18
33
  ext: 'png',
19
34
  mime: 'image/png'
20
35
  };
21
36
  }
22
37
 
23
- if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46) {
38
+ if (check([0x47, 0x49, 0x46])) {
24
39
  return {
25
40
  ext: 'gif',
26
41
  mime: 'image/gif'
27
42
  };
28
43
  }
29
44
 
30
- if (buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) {
45
+ if (check([0x57, 0x45, 0x42, 0x50], {offset: 8})) {
31
46
  return {
32
47
  ext: 'webp',
33
48
  mime: 'image/webp'
34
49
  };
35
50
  }
36
51
 
37
- if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x49 && buf[3] === 0x46) {
52
+ if (check([0x46, 0x4C, 0x49, 0x46])) {
38
53
  return {
39
54
  ext: 'flif',
40
55
  mime: 'image/flif'
41
56
  };
42
57
  }
43
58
 
44
- // needs to be before `tif` check
45
- if (((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) && buf[8] === 0x43 && buf[9] === 0x52) {
59
+ // Needs to be before `tif` check
60
+ if (
61
+ (check([0x49, 0x49, 0x2A, 0x0]) || check([0x4D, 0x4D, 0x0, 0x2A])) &&
62
+ check([0x43, 0x52], {offset: 8})
63
+ ) {
46
64
  return {
47
65
  ext: 'cr2',
48
66
  mime: 'image/x-canon-cr2'
49
67
  };
50
68
  }
51
69
 
52
- if ((buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0x2A && buf[3] === 0x0) || (buf[0] === 0x4D && buf[1] === 0x4D && buf[2] === 0x0 && buf[3] === 0x2A)) {
70
+ if (
71
+ check([0x49, 0x49, 0x2A, 0x0]) ||
72
+ check([0x4D, 0x4D, 0x0, 0x2A])
73
+ ) {
53
74
  return {
54
75
  ext: 'tif',
55
76
  mime: 'image/tiff'
56
77
  };
57
78
  }
58
79
 
59
- if (buf[0] === 0x42 && buf[1] === 0x4D) {
80
+ if (check([0x42, 0x4D])) {
60
81
  return {
61
82
  ext: 'bmp',
62
83
  mime: 'image/bmp'
63
84
  };
64
85
  }
65
86
 
66
- if (buf[0] === 0x49 && buf[1] === 0x49 && buf[2] === 0xBC) {
87
+ if (check([0x49, 0x49, 0xBC])) {
67
88
  return {
68
89
  ext: 'jxr',
69
90
  mime: 'image/vnd.ms-photo'
70
91
  };
71
92
  }
72
93
 
73
- if (buf[0] === 0x38 && buf[1] === 0x42 && buf[2] === 0x50 && buf[3] === 0x53) {
94
+ if (check([0x38, 0x42, 0x50, 0x53])) {
74
95
  return {
75
96
  ext: 'psd',
76
97
  mime: 'image/vnd.adobe.photoshop'
77
98
  };
78
99
  }
79
100
 
80
- // needs to be before `zip` check
81
- if (buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x6D && buf[31] === 0x69 && buf[32] === 0x6D && buf[33] === 0x65 && buf[34] === 0x74 && buf[35] === 0x79 && buf[36] === 0x70 && buf[37] === 0x65 && buf[38] === 0x61 && buf[39] === 0x70 && buf[40] === 0x70 && buf[41] === 0x6C && buf[42] === 0x69 && buf[43] === 0x63 && buf[44] === 0x61 && buf[45] === 0x74 && buf[46] === 0x69 && buf[47] === 0x6F && buf[48] === 0x6E && buf[49] === 0x2F && buf[50] === 0x65 && buf[51] === 0x70 && buf[52] === 0x75 && buf[53] === 0x62 && buf[54] === 0x2B && buf[55] === 0x7A && buf[56] === 0x69 && buf[57] === 0x70) {
101
+ // Needs to be before the `zip` check
102
+ if (
103
+ check([0x50, 0x4B, 0x3, 0x4]) &&
104
+ check([0x6D, 0x69, 0x6D, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70, 0x70, 0x6C, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x65, 0x70, 0x75, 0x62, 0x2B, 0x7A, 0x69, 0x70], {offset: 30})
105
+ ) {
82
106
  return {
83
107
  ext: 'epub',
84
108
  mime: 'application/epub+zip'
85
109
  };
86
110
  }
87
111
 
88
- // needs to be before `zip` check
89
- // assumes signed .xpi from addons.mozilla.org
90
- if (buf[0] === 0x50 && buf[1] === 0x4B && buf[2] === 0x3 && buf[3] === 0x4 && buf[30] === 0x4D && buf[31] === 0x45 && buf[32] === 0x54 && buf[33] === 0x41 && buf[34] === 0x2D && buf[35] === 0x49 && buf[36] === 0x4E && buf[37] === 0x46 && buf[38] === 0x2F && buf[39] === 0x6D && buf[40] === 0x6F && buf[41] === 0x7A && buf[42] === 0x69 && buf[43] === 0x6C && buf[44] === 0x6C && buf[45] === 0x61 && buf[46] === 0x2E && buf[47] === 0x72 && buf[48] === 0x73 && buf[49] === 0x61) {
112
+ // Needs to be before `zip` check
113
+ // Assumes signed `.xpi` from addons.mozilla.org
114
+ if (
115
+ check([0x50, 0x4B, 0x3, 0x4]) &&
116
+ check([0x4D, 0x45, 0x54, 0x41, 0x2D, 0x49, 0x4E, 0x46, 0x2F, 0x6D, 0x6F, 0x7A, 0x69, 0x6C, 0x6C, 0x61, 0x2E, 0x72, 0x73, 0x61], {offset: 30})
117
+ ) {
91
118
  return {
92
119
  ext: 'xpi',
93
120
  mime: 'application/x-xpinstall'
94
121
  };
95
122
  }
96
123
 
97
- if (buf[0] === 0x50 && buf[1] === 0x4B && (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) && (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)) {
124
+ if (
125
+ check([0x50, 0x4B]) &&
126
+ (buf[2] === 0x3 || buf[2] === 0x5 || buf[2] === 0x7) &&
127
+ (buf[3] === 0x4 || buf[3] === 0x6 || buf[3] === 0x8)
128
+ ) {
98
129
  return {
99
130
  ext: 'zip',
100
131
  mime: 'application/zip'
101
132
  };
102
133
  }
103
134
 
104
- if (buf[257] === 0x75 && buf[258] === 0x73 && buf[259] === 0x74 && buf[260] === 0x61 && buf[261] === 0x72) {
135
+ if (check([0x75, 0x73, 0x74, 0x61, 0x72], {offset: 257})) {
105
136
  return {
106
137
  ext: 'tar',
107
138
  mime: 'application/x-tar'
108
139
  };
109
140
  }
110
141
 
111
- if (buf[0] === 0x52 && buf[1] === 0x61 && buf[2] === 0x72 && buf[3] === 0x21 && buf[4] === 0x1A && buf[5] === 0x7 && (buf[6] === 0x0 || buf[6] === 0x1)) {
142
+ if (
143
+ check([0x52, 0x61, 0x72, 0x21, 0x1A, 0x7]) &&
144
+ (buf[6] === 0x0 || buf[6] === 0x1)
145
+ ) {
112
146
  return {
113
147
  ext: 'rar',
114
148
  mime: 'application/x-rar-compressed'
115
149
  };
116
150
  }
117
151
 
118
- if (buf[0] === 0x1F && buf[1] === 0x8B && buf[2] === 0x8) {
152
+ if (check([0x1F, 0x8B, 0x8])) {
119
153
  return {
120
154
  ext: 'gz',
121
155
  mime: 'application/gzip'
122
156
  };
123
157
  }
124
158
 
125
- if (buf[0] === 0x42 && buf[1] === 0x5A && buf[2] === 0x68) {
159
+ if (check([0x42, 0x5A, 0x68])) {
126
160
  return {
127
161
  ext: 'bz2',
128
162
  mime: 'application/x-bzip2'
129
163
  };
130
164
  }
131
165
 
132
- if (buf[0] === 0x37 && buf[1] === 0x7A && buf[2] === 0xBC && buf[3] === 0xAF && buf[4] === 0x27 && buf[5] === 0x1C) {
166
+ if (check([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) {
133
167
  return {
134
168
  ext: '7z',
135
169
  mime: 'application/x-7z-compressed'
136
170
  };
137
171
  }
138
172
 
139
- if (buf[0] === 0x78 && buf[1] === 0x01) {
173
+ if (check([0x78, 0x01])) {
140
174
  return {
141
175
  ext: 'dmg',
142
176
  mime: 'application/x-apple-diskimage'
@@ -144,11 +178,18 @@ module.exports = input => {
144
178
  }
145
179
 
146
180
  if (
147
- (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && (buf[3] === 0x18 || buf[3] === 0x20) && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) ||
148
- (buf[0] === 0x33 && buf[1] === 0x67 && buf[2] === 0x70 && buf[3] === 0x35) ||
149
- (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && buf[11] === 0x32 && buf[16] === 0x6D && buf[17] === 0x70 && buf[18] === 0x34 && buf[19] === 0x31 && buf[20] === 0x6D && buf[21] === 0x70 && buf[22] === 0x34 && buf[23] === 0x32 && buf[24] === 0x69 && buf[25] === 0x73 && buf[26] === 0x6F && buf[27] === 0x6D) ||
150
- (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x69 && buf[9] === 0x73 && buf[10] === 0x6F && buf[11] === 0x6D) ||
151
- (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1c && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x6D && buf[9] === 0x70 && buf[10] === 0x34 && buf[11] === 0x32 && buf[12] === 0x0 && buf[13] === 0x0 && buf[14] === 0x0 && buf[15] === 0x0)
181
+ (
182
+ check([0x0, 0x0, 0x0]) &&
183
+ (buf[3] === 0x18 || buf[3] === 0x20) &&
184
+ check([0x66, 0x74, 0x79, 0x70], {offset: 4})
185
+ ) ||
186
+ check([0x33, 0x67, 0x70, 0x35]) ||
187
+ (
188
+ check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32]) &&
189
+ check([0x6D, 0x70, 0x34, 0x31, 0x6D, 0x70, 0x34, 0x32, 0x69, 0x73, 0x6F, 0x6D], {offset: 16})
190
+ ) ||
191
+ check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D]) ||
192
+ check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32, 0x0, 0x0, 0x0, 0x0])
152
193
  ) {
153
194
  return {
154
195
  ext: 'mp4',
@@ -156,14 +197,14 @@ module.exports = input => {
156
197
  };
157
198
  }
158
199
 
159
- if ((buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x1C && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x56)) {
200
+ if (check([0x0, 0x0, 0x0, 0x1C, 0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x56])) {
160
201
  return {
161
202
  ext: 'm4v',
162
203
  mime: 'video/x-m4v'
163
204
  };
164
205
  }
165
206
 
166
- if (buf[0] === 0x4D && buf[1] === 0x54 && buf[2] === 0x68 && buf[3] === 0x64) {
207
+ if (check([0x4D, 0x54, 0x68, 0x64])) {
167
208
  return {
168
209
  ext: 'mid',
169
210
  mime: 'audio/midi'
@@ -171,7 +212,7 @@ module.exports = input => {
171
212
  }
172
213
 
173
214
  // https://github.com/threatstack/libmagic/blob/master/magic/Magdir/matroska
174
- if (buf[0] === 0x1A && buf[1] === 0x45 && buf[2] === 0xDF && buf[3] === 0xA3) {
215
+ if (check([0x1A, 0x45, 0xDF, 0xA3])) {
175
216
  const sliced = buf.subarray(4, 4 + 4096);
176
217
  const idPos = sliced.findIndex((el, i, arr) => arr[i] === 0x42 && arr[i + 1] === 0x82);
177
218
 
@@ -185,6 +226,7 @@ module.exports = input => {
185
226
  mime: 'video/x-matroska'
186
227
  };
187
228
  }
229
+
188
230
  if (findDocType('webm')) {
189
231
  return {
190
232
  ext: 'webm',
@@ -194,117 +236,143 @@ module.exports = input => {
194
236
  }
195
237
  }
196
238
 
197
- if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x0 && buf[3] === 0x14 && buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70) {
239
+ if (check([0x0, 0x0, 0x0, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]) ||
240
+ check([0x66, 0x72, 0x65, 0x65], {offset: 4}) ||
241
+ check([0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20], {offset: 4}) ||
242
+ check([0x6D, 0x64, 0x61, 0x74], {offset: 4}) || // MJPEG
243
+ check([0x77, 0x69, 0x64, 0x65], {offset: 4})) {
198
244
  return {
199
245
  ext: 'mov',
200
246
  mime: 'video/quicktime'
201
247
  };
202
248
  }
203
249
 
204
- if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x41 && buf[9] === 0x56 && buf[10] === 0x49) {
250
+ if (
251
+ check([0x52, 0x49, 0x46, 0x46]) &&
252
+ check([0x41, 0x56, 0x49], {offset: 8})
253
+ ) {
205
254
  return {
206
255
  ext: 'avi',
207
256
  mime: 'video/x-msvideo'
208
257
  };
209
258
  }
210
259
 
211
- if (buf[0] === 0x30 && buf[1] === 0x26 && buf[2] === 0xB2 && buf[3] === 0x75 && buf[4] === 0x8E && buf[5] === 0x66 && buf[6] === 0xCF && buf[7] === 0x11 && buf[8] === 0xA6 && buf[9] === 0xD9) {
260
+ if (check([0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9])) {
212
261
  return {
213
262
  ext: 'wmv',
214
263
  mime: 'video/x-ms-wmv'
215
264
  };
216
265
  }
217
266
 
218
- if (buf[0] === 0x0 && buf[1] === 0x0 && buf[2] === 0x1 && buf[3].toString(16)[0] === 'b') {
267
+ if (check([0x0, 0x0, 0x1, 0xBA])) {
219
268
  return {
220
269
  ext: 'mpg',
221
270
  mime: 'video/mpeg'
222
271
  };
223
272
  }
224
273
 
225
- if ((buf[0] === 0x49 && buf[1] === 0x44 && buf[2] === 0x33) || (buf[0] === 0xFF && buf[1] === 0xfb)) {
274
+ if (
275
+ check([0x49, 0x44, 0x33]) ||
276
+ check([0xFF, 0xFB])
277
+ ) {
226
278
  return {
227
279
  ext: 'mp3',
228
280
  mime: 'audio/mpeg'
229
281
  };
230
282
  }
231
283
 
232
- if ((buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70 && buf[8] === 0x4D && buf[9] === 0x34 && buf[10] === 0x41) || (buf[0] === 0x4D && buf[1] === 0x34 && buf[2] === 0x41 && buf[3] === 0x20)) {
284
+ if (
285
+ check([0x66, 0x74, 0x79, 0x70, 0x4D, 0x34, 0x41], {offset: 4}) ||
286
+ check([0x4D, 0x34, 0x41, 0x20])
287
+ ) {
233
288
  return {
234
289
  ext: 'm4a',
235
290
  mime: 'audio/m4a'
236
291
  };
237
292
  }
238
293
 
239
- // needs to be before `ogg` check
240
- if (buf[28] === 0x4F && buf[29] === 0x70 && buf[30] === 0x75 && buf[31] === 0x73 && buf[32] === 0x48 && buf[33] === 0x65 && buf[34] === 0x61 && buf[35] === 0x64) {
294
+ // Needs to be before `ogg` check
295
+ if (check([0x4F, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64], {offset: 28})) {
241
296
  return {
242
297
  ext: 'opus',
243
298
  mime: 'audio/opus'
244
299
  };
245
300
  }
246
301
 
247
- if (buf[0] === 0x4F && buf[1] === 0x67 && buf[2] === 0x67 && buf[3] === 0x53) {
302
+ if (check([0x4F, 0x67, 0x67, 0x53])) {
248
303
  return {
249
304
  ext: 'ogg',
250
305
  mime: 'audio/ogg'
251
306
  };
252
307
  }
253
308
 
254
- if (buf[0] === 0x66 && buf[1] === 0x4C && buf[2] === 0x61 && buf[3] === 0x43) {
309
+ if (check([0x66, 0x4C, 0x61, 0x43])) {
255
310
  return {
256
311
  ext: 'flac',
257
312
  mime: 'audio/x-flac'
258
313
  };
259
314
  }
260
315
 
261
- if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 && buf[8] === 0x57 && buf[9] === 0x41 && buf[10] === 0x56 && buf[11] === 0x45) {
316
+ if (
317
+ check([0x52, 0x49, 0x46, 0x46]) &&
318
+ check([0x57, 0x41, 0x56, 0x45], {offset: 8})
319
+ ) {
262
320
  return {
263
321
  ext: 'wav',
264
322
  mime: 'audio/x-wav'
265
323
  };
266
324
  }
267
325
 
268
- if (buf[0] === 0x23 && buf[1] === 0x21 && buf[2] === 0x41 && buf[3] === 0x4D && buf[4] === 0x52 && buf[5] === 0x0A) {
326
+ if (check([0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A])) {
269
327
  return {
270
328
  ext: 'amr',
271
329
  mime: 'audio/amr'
272
330
  };
273
331
  }
274
332
 
275
- if (buf[0] === 0x25 && buf[1] === 0x50 && buf[2] === 0x44 && buf[3] === 0x46) {
333
+ if (check([0x25, 0x50, 0x44, 0x46])) {
276
334
  return {
277
335
  ext: 'pdf',
278
336
  mime: 'application/pdf'
279
337
  };
280
338
  }
281
339
 
282
- if (buf[0] === 0x4D && buf[1] === 0x5A) {
340
+ if (check([0x4D, 0x5A])) {
283
341
  return {
284
342
  ext: 'exe',
285
343
  mime: 'application/x-msdownload'
286
344
  };
287
345
  }
288
346
 
289
- if ((buf[0] === 0x43 || buf[0] === 0x46) && buf[1] === 0x57 && buf[2] === 0x53) {
347
+ if (
348
+ (buf[0] === 0x43 || buf[0] === 0x46) &&
349
+ check([0x57, 0x53], {offset: 1})
350
+ ) {
290
351
  return {
291
352
  ext: 'swf',
292
353
  mime: 'application/x-shockwave-flash'
293
354
  };
294
355
  }
295
356
 
296
- if (buf[0] === 0x7B && buf[1] === 0x5C && buf[2] === 0x72 && buf[3] === 0x74 && buf[4] === 0x66) {
357
+ if (check([0x7B, 0x5C, 0x72, 0x74, 0x66])) {
297
358
  return {
298
359
  ext: 'rtf',
299
360
  mime: 'application/rtf'
300
361
  };
301
362
  }
302
363
 
364
+ if (check([0x00, 0x61, 0x73, 0x6D])) {
365
+ return {
366
+ ext: 'wasm',
367
+ mime: 'application/wasm'
368
+ };
369
+ }
370
+
303
371
  if (
304
- (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x46) &&
372
+ check([0x77, 0x4F, 0x46, 0x46]) &&
305
373
  (
306
- (buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) ||
307
- (buf[4] === 0x4F && buf[5] === 0x54 && buf[6] === 0x54 && buf[7] === 0x4F)
374
+ check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
375
+ check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
308
376
  )
309
377
  ) {
310
378
  return {
@@ -314,10 +382,10 @@ module.exports = input => {
314
382
  }
315
383
 
316
384
  if (
317
- (buf[0] === 0x77 && buf[1] === 0x4F && buf[2] === 0x46 && buf[3] === 0x32) &&
385
+ check([0x77, 0x4F, 0x46, 0x32]) &&
318
386
  (
319
- (buf[4] === 0x00 && buf[5] === 0x01 && buf[6] === 0x00 && buf[7] === 0x00) ||
320
- (buf[4] === 0x4F && buf[5] === 0x54 && buf[6] === 0x54 && buf[7] === 0x4F)
387
+ check([0x00, 0x01, 0x00, 0x00], {offset: 4}) ||
388
+ check([0x4F, 0x54, 0x54, 0x4F], {offset: 4})
321
389
  )
322
390
  ) {
323
391
  return {
@@ -327,11 +395,11 @@ module.exports = input => {
327
395
  }
328
396
 
329
397
  if (
330
- (buf[34] === 0x4C && buf[35] === 0x50) &&
398
+ check([0x4C, 0x50], {offset: 34}) &&
331
399
  (
332
- (buf[8] === 0x00 && buf[9] === 0x00 && buf[10] === 0x01) ||
333
- (buf[8] === 0x01 && buf[9] === 0x00 && buf[10] === 0x02) ||
334
- (buf[8] === 0x02 && buf[9] === 0x00 && buf[10] === 0x02)
400
+ check([0x00, 0x00, 0x01], {offset: 8}) ||
401
+ check([0x01, 0x00, 0x02], {offset: 8}) ||
402
+ check([0x02, 0x00, 0x02], {offset: 8})
335
403
  )
336
404
  ) {
337
405
  return {
@@ -340,63 +408,63 @@ module.exports = input => {
340
408
  };
341
409
  }
342
410
 
343
- if (buf[0] === 0x00 && buf[1] === 0x01 && buf[2] === 0x00 && buf[3] === 0x00 && buf[4] === 0x00) {
411
+ if (check([0x00, 0x01, 0x00, 0x00, 0x00])) {
344
412
  return {
345
413
  ext: 'ttf',
346
414
  mime: 'application/font-sfnt'
347
415
  };
348
416
  }
349
417
 
350
- if (buf[0] === 0x4F && buf[1] === 0x54 && buf[2] === 0x54 && buf[3] === 0x4F && buf[4] === 0x00) {
418
+ if (check([0x4F, 0x54, 0x54, 0x4F, 0x00])) {
351
419
  return {
352
420
  ext: 'otf',
353
421
  mime: 'application/font-sfnt'
354
422
  };
355
423
  }
356
424
 
357
- if (buf[0] === 0x00 && buf[1] === 0x00 && buf[2] === 0x01 && buf[3] === 0x00) {
425
+ if (check([0x00, 0x00, 0x01, 0x00])) {
358
426
  return {
359
427
  ext: 'ico',
360
428
  mime: 'image/x-icon'
361
429
  };
362
430
  }
363
431
 
364
- if (buf[0] === 0x46 && buf[1] === 0x4C && buf[2] === 0x56 && buf[3] === 0x01) {
432
+ if (check([0x46, 0x4C, 0x56, 0x01])) {
365
433
  return {
366
434
  ext: 'flv',
367
435
  mime: 'video/x-flv'
368
436
  };
369
437
  }
370
438
 
371
- if (buf[0] === 0x25 && buf[1] === 0x21) {
439
+ if (check([0x25, 0x21])) {
372
440
  return {
373
441
  ext: 'ps',
374
442
  mime: 'application/postscript'
375
443
  };
376
444
  }
377
445
 
378
- if (buf[0] === 0xFD && buf[1] === 0x37 && buf[2] === 0x7A && buf[3] === 0x58 && buf[4] === 0x5A && buf[5] === 0x00) {
446
+ if (check([0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00])) {
379
447
  return {
380
448
  ext: 'xz',
381
449
  mime: 'application/x-xz'
382
450
  };
383
451
  }
384
452
 
385
- if (buf[0] === 0x53 && buf[1] === 0x51 && buf[2] === 0x4C && buf[3] === 0x69) {
453
+ if (check([0x53, 0x51, 0x4C, 0x69])) {
386
454
  return {
387
455
  ext: 'sqlite',
388
456
  mime: 'application/x-sqlite3'
389
457
  };
390
458
  }
391
459
 
392
- if (buf[0] === 0x4E && buf[1] === 0x45 && buf[2] === 0x53 && buf[3] === 0x1A) {
460
+ if (check([0x4E, 0x45, 0x53, 0x1A])) {
393
461
  return {
394
462
  ext: 'nes',
395
463
  mime: 'application/x-nintendo-nes-rom'
396
464
  };
397
465
  }
398
466
 
399
- if (buf[0] === 0x43 && buf[1] === 0x72 && buf[2] === 0x32 && buf[3] === 0x34) {
467
+ if (check([0x43, 0x72, 0x32, 0x34])) {
400
468
  return {
401
469
  ext: 'crx',
402
470
  mime: 'application/x-google-chrome-extension'
@@ -404,8 +472,8 @@ module.exports = input => {
404
472
  }
405
473
 
406
474
  if (
407
- (buf[0] === 0x4D && buf[1] === 0x53 && buf[2] === 0x43 && buf[3] === 0x46) ||
408
- (buf[0] === 0x49 && buf[1] === 0x53 && buf[2] === 0x63 && buf[3] === 0x28)
475
+ check([0x4D, 0x53, 0x43, 0x46]) ||
476
+ check([0x49, 0x53, 0x63, 0x28])
409
477
  ) {
410
478
  return {
411
479
  ext: 'cab',
@@ -413,22 +481,22 @@ module.exports = input => {
413
481
  };
414
482
  }
415
483
 
416
- // needs to be before `ar` check
417
- if (buf[0] === 0x21 && buf[1] === 0x3C && buf[2] === 0x61 && buf[3] === 0x72 && buf[4] === 0x63 && buf[5] === 0x68 && buf[6] === 0x3E && buf[7] === 0x0A && buf[8] === 0x64 && buf[9] === 0x65 && buf[10] === 0x62 && buf[11] === 0x69 && buf[12] === 0x61 && buf[13] === 0x6E && buf[14] === 0x2D && buf[15] === 0x62 && buf[16] === 0x69 && buf[17] === 0x6E && buf[18] === 0x61 && buf[19] === 0x72 && buf[20] === 0x79) {
484
+ // Needs to be before `ar` check
485
+ if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E, 0x0A, 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D, 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79])) {
418
486
  return {
419
487
  ext: 'deb',
420
488
  mime: 'application/x-deb'
421
489
  };
422
490
  }
423
491
 
424
- if (buf[0] === 0x21 && buf[1] === 0x3C && buf[2] === 0x61 && buf[3] === 0x72 && buf[4] === 0x63 && buf[5] === 0x68 && buf[6] === 0x3E) {
492
+ if (check([0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E])) {
425
493
  return {
426
494
  ext: 'ar',
427
495
  mime: 'application/x-unix-archive'
428
496
  };
429
497
  }
430
498
 
431
- if (buf[0] === 0xED && buf[1] === 0xAB && buf[2] === 0xEE && buf[3] === 0xDB) {
499
+ if (check([0xED, 0xAB, 0xEE, 0xDB])) {
432
500
  return {
433
501
  ext: 'rpm',
434
502
  mime: 'application/x-rpm'
@@ -436,8 +504,8 @@ module.exports = input => {
436
504
  }
437
505
 
438
506
  if (
439
- (buf[0] === 0x1F && buf[1] === 0xA0) ||
440
- (buf[0] === 0x1F && buf[1] === 0x9D)
507
+ check([0x1F, 0xA0]) ||
508
+ check([0x1F, 0x9D])
441
509
  ) {
442
510
  return {
443
511
  ext: 'Z',
@@ -445,19 +513,33 @@ module.exports = input => {
445
513
  };
446
514
  }
447
515
 
448
- if (buf[0] === 0x4C && buf[1] === 0x5A && buf[2] === 0x49 && buf[3] === 0x50) {
516
+ if (check([0x4C, 0x5A, 0x49, 0x50])) {
449
517
  return {
450
518
  ext: 'lz',
451
519
  mime: 'application/x-lzip'
452
520
  };
453
521
  }
454
522
 
455
- if (buf[0] === 0xD0 && buf[1] === 0xCF && buf[2] === 0x11 && buf[3] === 0xE0 && buf[4] === 0xA1 && buf[5] === 0xB1 && buf[6] === 0x1A && buf[7] === 0xE1) {
523
+ if (check([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) {
456
524
  return {
457
525
  ext: 'msi',
458
526
  mime: 'application/x-msi'
459
527
  };
460
528
  }
461
529
 
530
+ if (check([0x06, 0x0E, 0x2B, 0x34, 0x02, 0x05, 0x01, 0x01, 0x0D, 0x01, 0x02, 0x01, 0x01, 0x02])) {
531
+ return {
532
+ ext: 'mxf',
533
+ mime: 'application/mxf'
534
+ };
535
+ }
536
+
537
+ if (check([0x42, 0x4C, 0x45, 0x4E, 0x44, 0x45, 0x52])) {
538
+ return {
539
+ ext: 'blend',
540
+ mime: 'application/x-blender'
541
+ };
542
+ }
543
+
462
544
  return null;
463
545
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "file-type",
3
- "version": "4.0.0",
3
+ "version": "4.4.0",
4
4
  "description": "Detect the file type of a Buffer/Uint8Array",
5
5
  "license": "MIT",
6
6
  "repository": "sindresorhus/file-type",
@@ -93,14 +93,15 @@
93
93
  "rpm",
94
94
  "Z",
95
95
  "lz",
96
- "msi"
96
+ "msi",
97
+ "mxf",
98
+ "wasm",
99
+ "webassembly",
100
+ "blend"
97
101
  ],
98
102
  "devDependencies": {
99
103
  "ava": "*",
100
104
  "read-chunk": "^2.0.0",
101
105
  "xo": "*"
102
- },
103
- "xo": {
104
- "esnext": true
105
106
  }
106
107
  }
package/readme.md CHANGED
@@ -59,16 +59,16 @@ xhr.send();
59
59
 
60
60
  ## API
61
61
 
62
- ### fileType(buffer)
62
+ ### fileType(input)
63
63
 
64
64
  Returns an `Object` with:
65
65
 
66
- - `ext` - one of the [supported file types](#supported-file-types)
67
- - `mime` - the [MIME type](http://en.wikipedia.org/wiki/Internet_media_type)
66
+ - `ext` - One of the [supported file types](#supported-file-types)
67
+ - `mime` - The [MIME type](http://en.wikipedia.org/wiki/Internet_media_type)
68
68
 
69
69
  Or `null` when no match.
70
70
 
71
- #### buffer
71
+ #### input
72
72
 
73
73
  Type: `Buffer` `Uint8Array`
74
74
 
@@ -135,10 +135,13 @@ It only needs the first 4100 bytes.
135
135
  - [`Z`](http://fileinfo.com/extension/z)
136
136
  - [`lz`](https://en.wikipedia.org/wiki/Lzip)
137
137
  - [`msi`](https://en.wikipedia.org/wiki/Windows_Installer)
138
+ - [`mxf`](https://en.wikipedia.org/wiki/Material_Exchange_Format)
139
+ - [`wasm`](https://en.wikipedia.org/wiki/WebAssembly)
140
+ - [`blend`](https://wiki.blender.org/index.php/Dev:Source/Architecture/File_Format)
138
141
 
139
142
  *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).*
140
143
 
141
- *PR welcome for additional commonly used file types.*
144
+ *Pull request welcome for additional commonly used file types.*
142
145
 
143
146
 
144
147
  ## Related