Skip to content

Commit

Permalink
Support for reading from Blob in Node.js
Browse files Browse the repository at this point in the history
  • Loading branch information
Borewit committed Mar 29, 2023
1 parent bb44bbc commit 2960eda
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 41 deletions.
38 changes: 1 addition & 37 deletions browser.js
@@ -1,36 +1,5 @@
import {Buffer} from 'node:buffer';
import {ReadableWebToNodeStream} from 'readable-web-to-node-stream';
import {fileTypeFromBuffer, fileTypeFromStream as coreFileTypeFromStream} from './core.js';

/**
Convert Blobs to ArrayBuffer.
@param {Blob} blob - Web API Blob.
@returns {Promise<ArrayBuffer>}
*/
function blobToArrayBuffer(blob) {
if (blob.arrayBuffer) {
return blob.arrayBuffer();
}

// TODO: Remove when stop supporting older environments
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.addEventListener('loadend', event => {
resolve(event.target.result);
});

fileReader.addEventListener('error', event => {
reject(new Error(event.message));
});

fileReader.addEventListener('abort', event => {
reject(new Error(event.type));
});

fileReader.readAsArrayBuffer(blob);
});
}
import {fileTypeFromStream as coreFileTypeFromStream} from './core.js';

export async function fileTypeFromStream(stream) {
const readableWebToNodeStream = new ReadableWebToNodeStream(stream);
Expand All @@ -39,11 +8,6 @@ export async function fileTypeFromStream(stream) {
return fileType;
}

export async function fileTypeFromBlob(blob) {
const buffer = await blobToArrayBuffer(blob);
return fileTypeFromBuffer(Buffer.from(buffer));
}

export {
fileTypeFromTokenizer,
fileTypeFromBuffer,
Expand Down
5 changes: 5 additions & 0 deletions core.js
Expand Up @@ -33,6 +33,11 @@ export async function fileTypeFromBuffer(input) {
return fileTypeFromTokenizer(strtok3.fromBuffer(buffer));
}

export async function fileTypeFromBlob(blob) {
const buffer = await blob.arrayBuffer();
return fileTypeFromBuffer(new Uint8Array(buffer));
}

function _check(buffer, headers, options) {
options = {
offset: 0,
Expand Down
2 changes: 0 additions & 2 deletions readme.md
Expand Up @@ -198,8 +198,6 @@ A readable stream representing file data.

Detect the file type of a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).

**Note:** This method is only available in the browser.

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.

Returns a `Promise` for an object with the detected file type and MIME type:
Expand Down
20 changes: 18 additions & 2 deletions test.js
@@ -1,5 +1,5 @@
import process from 'node:process';
import {Buffer} from 'node:buffer';
import {Buffer, Blob} from 'node:buffer';
import path from 'node:path';
import {fileURLToPath} from 'node:url';
import fs from 'node:fs';
Expand All @@ -13,7 +13,7 @@ import {
fileTypeFromFile,
fileTypeStream,
supportedExtensions,
supportedMimeTypes,
supportedMimeTypes, fileTypeFromBlob,
} from './index.js';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -262,6 +262,13 @@ async function checkBufferLike(t, type, bufferLike) {
t.is(typeof mime, 'string');
}

async function checkBlobLike(t, type, bufferLike) {
const blob = new Blob([bufferLike]);
const {ext, mime} = await fileTypeFromBlob(blob) ?? {};
t.is(ext, type);
t.is(typeof mime, 'string');
}

async function checkFile(t, type, filePath) {
const {ext, mime} = await fileTypeFromFile(filePath) ?? {};
t.is(ext, type);
Expand All @@ -283,6 +290,14 @@ async function testFromBuffer(t, ext, name) {
await checkBufferLike(t, ext, chunk.buffer.slice(chunk.byteOffset, chunk.byteOffset + chunk.byteLength));
}

async function testFromBlob(t, ext, name) {
const fixtureName = `${(name ?? 'fixture')}.${ext}`;

const file = path.join(__dirname, 'fixture', fixtureName);
const chunk = fs.readFileSync(file);
await checkBlobLike(t, ext, chunk);
}

async function testFalsePositive(t, ext, name) {
const file = path.join(__dirname, 'fixture', `${name}.${ext}`);

Expand Down Expand Up @@ -334,6 +349,7 @@ for (const type of types) {

_test(`${name}.${type} ${i++} .fileTypeFromFile() method - same fileType`, testFromFile, type, name);
_test(`${name}.${type} ${i++} .fileTypeFromBuffer() method - same fileType`, testFromBuffer, type, name);
_test(`${name}.${type} ${i++} .fileTypeFromBlob() method - same fileType`, testFromBlob, type, name);
_test(`${name}.${type} ${i++} .fileTypeFromStream() method - same fileType`, testFileFromStream, type, name);
test(`${name}.${type} ${i++} .fileTypeStream() - identical streams`, testStream, type, name);
}
Expand Down

0 comments on commit 2960eda

Please sign in to comment.