-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9206911
Showing
8 changed files
with
1,188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/node_modules/ | ||
/npm-debug.log |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
const fileType = require('file-type') | ||
const Transform = require('readable-stream/transform') | ||
|
||
const kChunks = Symbol('chunks') | ||
const kLength = Symbol('length') | ||
const kDone = Symbol('done') | ||
const kResult = Symbol('result') | ||
const kEmitFileType = Symbol('emit-file-type') | ||
|
||
const TARGET_BYTES = 4100 | ||
|
||
class FileType extends Transform { | ||
constructor () { | ||
super() | ||
|
||
this[kChunks] = [] | ||
this[kLength] = 0 | ||
this[kDone] = false | ||
this[kResult] = null | ||
} | ||
|
||
fileTypePromise () { | ||
return new Promise((resolve, reject) => { | ||
if (this[kDone]) return resolve(this[kResult]) | ||
|
||
this.once('error', reject) | ||
this.once('file-type', resolve) | ||
}) | ||
} | ||
|
||
[kEmitFileType] () { | ||
this[kDone] = true | ||
this[kResult] = fileType(Buffer.concat(this[kChunks])) | ||
|
||
this.emit('file-type', this[kResult]) | ||
|
||
delete this[kChunks] | ||
delete this[kLength] | ||
} | ||
|
||
_transform (chunk, _, cb) { | ||
if (!this[kDone]) { | ||
this[kChunks].push(chunk) | ||
this[kLength] += chunk.length | ||
|
||
if (this[kLength] >= TARGET_BYTES) { | ||
this[kEmitFileType]() | ||
} | ||
} | ||
|
||
cb(null, chunk) | ||
} | ||
|
||
_flush (cb) { | ||
if (!this[kDone]) { | ||
this[kEmitFileType]() | ||
} | ||
|
||
cb(null) | ||
} | ||
} | ||
|
||
module.exports = FileType |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "stream-file-type", | ||
"version": "0.0.0", | ||
"license": "MIT", | ||
"repository": "LinusU/stream-file-type", | ||
"scripts": { | ||
"test": "standard && mocha" | ||
}, | ||
"dependencies": { | ||
"file-type": "^4.1.0", | ||
"readable-stream": "^2.2.2" | ||
}, | ||
"devDependencies": { | ||
"hasha": "^2.2.0", | ||
"mocha": "^3.2.0", | ||
"standard": "^8.6.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# Stream File Type | ||
|
||
Get the [file type](https://github.com/sindresorhus/file-type) by inspecting a stream. | ||
|
||
## Usage | ||
|
||
```js | ||
const fs = require('fs') | ||
const FileType = require('stream-file-type') | ||
|
||
const input = fs.createReadStream('cat.jpg') | ||
const detector = new FileType() | ||
|
||
detector.on('file-type', (fileType) => { | ||
if (fileType === null) { | ||
console.log(`The mime type of "cat.jpg" could not be determined`) | ||
} else { | ||
console.log(`The file "cat.jpg" has the "${fileType.mime}" mime type`) | ||
} | ||
}) | ||
|
||
input.pipe(detector).resume() | ||
``` | ||
|
||
## API | ||
|
||
### `new FileType() => DuplexStream` | ||
|
||
Returns a new `DuplexStream` that will detect the file type of the content passing thru. All the data is passed as-is right thru the stream, and can be further piped to another destination. | ||
|
||
When enough bytes have come thru to determine the file type (currently 4100) the event `file-type` will be emitted with the result of the detection. The result will either be `null` or an object with `ext` and `mime`. | ||
|
||
- `ext` - One of the [supported file types](https://github.com/sindresorhus/file-type#supported-file-types) | ||
- `mime` - The [MIME type](http://en.wikipedia.org/wiki/Internet_media_type) | ||
|
||
### `FileType#fileTypePromise() => Promise` | ||
|
||
Returns a `Promise` of the detected file type. If the `file-type` event has already been emitted, the promise will be resolved with the result, otherwise the promise will be resolved when the file-type is detected, or rejected if an error occurs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* eslint-env mocha */ | ||
|
||
const fs = require('fs') | ||
const assert = require('assert') | ||
const hasha = require('hasha') | ||
|
||
const FileType = require('./') | ||
|
||
describe('stream-file-type', () => { | ||
it('should detect the file type of a stream', () => { | ||
const input = fs.createReadStream('fixture/fixture.mid') | ||
const detector = new FileType() | ||
|
||
input.pipe(detector).resume() | ||
|
||
let emitted | ||
detector.on('file-type', fileType => { emitted = fileType }) | ||
|
||
return detector.fileTypePromise() | ||
.then(type => assert.deepEqual(type, { ext: 'mid', mime: 'audio/midi' })) | ||
.then(() => assert.deepEqual(emitted, { ext: 'mid', mime: 'audio/midi' })) | ||
}) | ||
|
||
it('should pass the input as-is', () => { | ||
const input = fs.createReadStream('fixture/fixture.mid') | ||
const detector = new FileType() | ||
|
||
return hasha.fromStream(input.pipe(detector), { algorithm: 'sha1' }) | ||
.then(hash => assert.equal(hash, '02cd79ed1d5f07eef736f79122aa89e6fe4f0d4b')) | ||
}) | ||
|
||
it('should handle files larger than 4100 bytes', () => { | ||
const input = fs.createReadStream('fixture/fixture-otto.woff2') | ||
const detector = new FileType() | ||
|
||
input.pipe(detector).resume() | ||
|
||
let emitted | ||
detector.on('file-type', fileType => { emitted = fileType }) | ||
|
||
return detector.fileTypePromise() | ||
.then(type => assert.deepEqual(type, { ext: 'woff2', mime: 'application/font-woff' })) | ||
.then(() => assert.deepEqual(emitted, { ext: 'woff2', mime: 'application/font-woff' })) | ||
}) | ||
}) |
Oops, something went wrong.