UNPKG

@rytass/storages

Version:
135 lines (130 loc) 4.85 kB
'use strict'; var fileConverter = require('@rytass/file-converter'); var stream = require('stream'); var crypto = require('crypto'); var buffer = require('buffer'); var fileType = require('file-type'); class StorageError extends Error { code; message; constructor(code, message){ super(message || ErrorDefaultMessage[code]); this.code = code; this.message = message || ErrorDefaultMessage[code]; } } var ErrorCode = /*#__PURE__*/ function(ErrorCode) { ErrorCode["WRITE_FILE_ERROR"] = "101"; ErrorCode["READ_FILE_ERROR"] = "102"; ErrorCode["REMOVE_FILE_ERROR"] = "103"; ErrorCode["UNRECOGNIZED_ERROR"] = "104"; ErrorCode["DIRECTORY_NOT_FOUND"] = "201"; ErrorCode["FILE_NOT_FOUND"] = "202"; return ErrorCode; }({}); const ErrorDefaultMessage = { ["101"]: 'WRITE_FILE_ERROR', ["102"]: 'READ_FILE_ERROR', ["103"]: 'REMOVE_FILE_ERROR', ["104"]: 'UNRECOGNIZED_ERROR', ["201"]: 'DIRECTORY_NOT_FOUND', ["202"]: 'FILE_NOT_FOUND' }; const MIN_BUFFER_LENGTH = 16; class Storage { converterManager; hashAlgorithm; constructor(options){ this.converterManager = new fileConverter.ConverterManager(options?.converters ?? []); this.hashAlgorithm = options?.hashAlgorithm || 'sha256'; } getExtension(file) { if (file instanceof buffer.Buffer) { return fileType.fileTypeFromBuffer(file); } const extensionStream = new stream.PassThrough(); file.pipe(extensionStream); return fileType.fileTypeFromStream(extensionStream); } async getBufferFilename(buffer) { const extension = await fileType.fileTypeFromBuffer(buffer); return [ `${crypto.createHash(this.hashAlgorithm).update(buffer).digest('hex')}${extension?.ext ? `.${extension.ext}` : ''}`, extension?.mime ?? undefined ]; } getStreamFilename(stream$1) { return new Promise((resolve, reject)=>{ const hashStream = new stream.PassThrough(); const extensionStream = new stream.PassThrough(); const getStreamHash = new Promise((subResolve)=>{ const hash = crypto.createHash(this.hashAlgorithm); hashStream.on('data', (buffer)=>{ hash.update(buffer); }); hashStream.on('end', ()=>{ subResolve(hash.digest('hex')); }); }); const getStreamFileType = new Promise((subResolve)=>{ let resolved = false; let isEnd = false; const bufferStorage = []; const waitingTasks = []; extensionStream.on('data', (buffer$1)=>{ if (resolved) return; bufferStorage.push(buffer$1); const targetBuffer = buffer.Buffer.concat(bufferStorage); if (targetBuffer.length >= MIN_BUFFER_LENGTH) { const taskIndex = waitingTasks.length; waitingTasks.push(true); fileType.fileTypeFromBuffer(targetBuffer).then((result)=>{ waitingTasks[taskIndex] = false; if (!result && !isEnd) return; resolved = true; subResolve(result); }); } else { waitingTasks.push(false); } }); extensionStream.on('end', ()=>{ isEnd = true; if (waitingTasks.every((task)=>!task) && !resolved) { resolved = true; subResolve(undefined); } }); }); Promise.all([ getStreamHash, getStreamFileType ]).then(([filename, extension])=>{ resolve([ `${filename}${extension?.ext ? `.${extension.ext}` : ''}`, extension?.mime ?? undefined ]); }).catch(reject); stream$1.pipe(hashStream).pipe(extensionStream); }); } write(_file, _options) { throw new Error('Method not implemented.'); } batchWrite(_files, _options) { throw new Error('Method not implemented.'); } read(_key, _options) { throw new Error('Method not implemented.'); } remove(_key) { throw new Error('Method not implemented.'); } isExists(_key) { throw new Error('Method not implemented.'); } } exports.ConverterManager = fileConverter.ConverterManager; exports.ErrorCode = ErrorCode; exports.Storage = Storage; exports.StorageError = StorageError;