UNPKG

@rytass/storages-adapter-local

Version:

Rytass Utils Storages local adapter

142 lines (137 loc) 5.19 kB
'use strict'; var storages = require('@rytass/storages'); var uuid = require('uuid'); var util = require('util'); var path = require('path'); var fs = require('fs'); var promises = require('fs/promises'); var child_process = require('child_process'); // @dev: for *NIX systems var StorageLocalHelperCommands = /*#__PURE__*/ function(StorageLocalHelperCommands) { StorageLocalHelperCommands["USED"] = "du -sm __DIR__ | awk '{ print $1 }'"; StorageLocalHelperCommands["FREE"] = "df -m __DIR__ | awk '$3 ~ /[0-9]+/ { print $4 }'"; StorageLocalHelperCommands["TOTAL"] = "df -m __DIR__ | awk '$3 ~ /[0-9]+/ { print $2 }'"; return StorageLocalHelperCommands; }({}); // @dev: using the const exec = util.promisify(child_process.exec); class LocalStorage extends storages.Storage { directory; constructor(options){ super(options); this.directory = options.directory; if (options.autoMkdir) { fs.mkdirSync(this.directory, { recursive: true }); } if (!fs.lstatSync(this.directory).isDirectory()) { throw new storages.StorageError(storages.ErrorCode.DIRECTORY_NOT_FOUND); } } async getUsageInfo() { const _usage = await this.getFsUsage(); return _usage; } // @dev: returns file system usage in 1M-blocks async getFsUsage() { const used = Number((await exec(StorageLocalHelperCommands.USED.replace('__DIR__', this.directory))).stdout); const free = Number((await exec(StorageLocalHelperCommands.FREE.replace('__DIR__', this.directory))).stdout); const total = Number((await exec(StorageLocalHelperCommands.TOTAL.replace('__DIR__', this.directory))).stdout); return { used, free, total }; } getFileFullPath(key) { return path.resolve(this.directory, key); } checkFileExists(fullPath) { try { if (!fs.lstatSync(fullPath).isFile()) { throw new storages.StorageError(storages.ErrorCode.FILE_NOT_FOUND); } } catch (_ex) { throw new storages.StorageError(storages.ErrorCode.FILE_NOT_FOUND); } } async writeBuffer(buffer, options) { const convertedBuffer = await this.converterManager.convert(buffer); const fileInfo = options?.filename || await this.getBufferFilename(buffer); const filename = Array.isArray(fileInfo) ? fileInfo[0] : fileInfo; await promises.writeFile(this.getFileFullPath(filename), convertedBuffer); return { key: filename }; } async writeStream(stream, options) { const convertedStream = await this.converterManager.convert(stream); if (options?.filename) { const writeStream = fs.createWriteStream(this.getFileFullPath(options.filename)); convertedStream.pipe(writeStream); await new Promise((resolve, reject)=>{ writeStream.on('finish', resolve); writeStream.on('error', reject); }); return { key: options.filename }; } const tempFilename = uuid.v4(); const writeStream = fs.createWriteStream(this.getFileFullPath(tempFilename)); convertedStream.pipe(writeStream); const [filename] = await this.getStreamFilename(convertedStream); // Wait for the write stream to finish before renaming await new Promise((resolve, reject)=>{ writeStream.on('finish', resolve); writeStream.on('error', reject); }); await promises.rename(this.getFileFullPath(tempFilename), this.getFileFullPath(filename)); return { key: filename }; } readFileBuffer(key) { const path = this.getFileFullPath(key); this.checkFileExists(path); return promises.readFile(path); } readFileStream(key) { const path = this.getFileFullPath(key); this.checkFileExists(path); return fs.createReadStream(path); } read(key, options) { if (options?.format === 'buffer') { return this.readFileBuffer(key); } return Promise.resolve(this.readFileStream(key)); } async write(file, options) { const convertedFile = await this.converterManager.convert(file); if (convertedFile instanceof Buffer) { return this.writeBuffer(convertedFile, options); } return this.writeStream(convertedFile, options); } batchWrite(files, options) { return Promise.all(files.map((file, index)=>this.write(file, options?.[index]))); } remove(key) { const path = this.getFileFullPath(key); this.checkFileExists(path); return promises.unlink(path); } async isExists(key) { const path = this.getFileFullPath(key); try { await this.checkFileExists(path); return true; } catch (_ex) { return false; } } } exports.LocalStorage = LocalStorage; exports.StorageLocalHelperCommands = StorageLocalHelperCommands;