@b2y/document-module
Version:
A flexible multi-provider storage adapter for file operations across S3, Azure Blob, Google Drive, and local storage
91 lines (81 loc) • 2.87 kB
JavaScript
// /storage/providers/LocalFileStorageProvider.js
const fs = require('fs').promises;
const path = require('path');
const BaseStorageProvider = require('./BaseStorageProvider');
const logger = require('../../logger');
class LocalFileStorageProvider extends BaseStorageProvider {
constructor() {
super();
this.baseDir = process.env.LOCAL_STORAGE_BASE_DIR || path.join(process.cwd(), 'uploads');
this.publicUrlBase = process.env.LOCAL_STORAGE_PUBLIC_URL_BASE || '/uploads';
}
async ensureDirectoryExists(dirPath) {
const fullPath = path.join(this.baseDir, dirPath);
await fs.mkdir(fullPath, { recursive: true });
return fullPath;
}
async uploadFile(file, destinationPath) {
try {
// Make sure the directory exists
const dirName = path.dirname(destinationPath);
await this.ensureDirectoryExists(dirName);
const fullPath = path.join(this.baseDir, destinationPath);
// If file is a buffer
if (Buffer.isBuffer(file)) {
await fs.writeFile(fullPath, file);
}
// If file is a path
else if (typeof file === 'string') {
const fileContent = await fs.readFile(file);
await fs.writeFile(fullPath, fileContent);
}
// If file is from multer
else if (file.path) {
const fileContent = await fs.readFile(file.path);
await fs.writeFile(fullPath, fileContent);
}
// If file is a stream
else if (file.stream) {
const writeStream = fs.createWriteStream(fullPath);
file.stream.pipe(writeStream);
await new Promise((resolve, reject) => {
writeStream.on('finish', resolve);
writeStream.on('error', reject);
});
}
return {
success: true,
path: destinationPath,
url: this.getPublicUrl(destinationPath)
};
} catch (error) {
logger.error('Error uploading to local file system:', error);
throw error;
}
}
async getFile(filePath) {
try {
const fullPath = path.join(this.baseDir, filePath);
return await fs.readFile(fullPath);
} catch (error) {
logger.error('Error getting file from local file system:', error);
throw error;
}
}
async deleteFile(filePath) {
try {
const fullPath = path.join(this.baseDir, filePath);
await fs.unlink(fullPath);
return { success: true };
} catch (error) {
logger.error('Error deleting file from local file system:', error);
throw error;
}
}
getPublicUrl(filePath) {
// Replace backslashes with forward slashes for URLs
const normalizedPath = filePath.replace(/\\/g, '/');
return `${this.publicUrlBase}/${normalizedPath}`;
}
}
module.exports = LocalFileStorageProvider;