express-storage
Version:
A simple and powerful file upload and storage management package for Express.js applications. Supports multiple storage drivers including S3, GCS, OCI, and local storage with presigned URL support.
102 lines • 3.61 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { BaseStorageDriver } from './base.driver.js';
import { createMonthBasedPath, ensureDirectoryExists, createLocalFileUrl } from '../utils/file.utils.js';
/**
* Local storage driver for file system storage
*/
export class LocalStorageDriver extends BaseStorageDriver {
constructor(config) {
super(config);
this.basePath = config.localPath || 'public/express-storage';
}
/**
* Upload file to local storage
*/
async upload(file) {
try {
// Validate file
const validationErrors = this.validateFile(file);
if (validationErrors.length > 0) {
return this.createErrorResult(validationErrors.join(', '));
}
// Generate unique filename
const fileName = this.generateFileName(file.originalname);
// Create month-based directory path
const monthPath = createMonthBasedPath(this.basePath);
const fullDirPath = path.resolve(monthPath);
// Ensure directory exists
ensureDirectoryExists(fullDirPath);
// Create full file path
const filePath = path.join(fullDirPath, fileName);
// Write file to disk
fs.writeFileSync(filePath, file.buffer);
// Generate relative URL
const relativePath = path.relative('public', filePath);
const fileUrl = createLocalFileUrl(relativePath);
return this.createSuccessResult(fileName, fileUrl);
}
catch (error) {
return this.createErrorResult(error instanceof Error ? error.message : 'Failed to upload file');
}
}
/**
* Generate upload URL (not supported for local storage)
*/
async generateUploadUrl(_fileName) {
return this.createPresignedErrorResult('Presigned URLs are not supported for local storage');
}
/**
* Generate view URL (not supported for local storage)
*/
async generateViewUrl(_fileName) {
return this.createPresignedErrorResult('Presigned URLs are not supported for local storage');
}
/**
* Delete file from local storage
*/
async delete(fileName) {
try {
// Find file in month directories
const filePath = this.findFilePath(fileName);
if (!filePath) {
return false;
}
// Delete file
fs.unlinkSync(filePath);
return true;
}
catch (error) {
return false;
}
}
/**
* Find file path by searching through month directories
*/
findFilePath(fileName) {
const baseDir = path.resolve(this.basePath);
if (!fs.existsSync(baseDir)) {
return null;
}
// Search through all subdirectories
const searchDirectories = (dir) => {
const items = fs.readdirSync(dir);
for (const item of items) {
const itemPath = path.join(dir, item);
const stat = fs.statSync(itemPath);
if (stat.isDirectory()) {
// Recursively search subdirectories
const found = searchDirectories(itemPath);
if (found)
return found;
}
else if (item === fileName) {
return itemPath;
}
}
return null;
};
return searchDirectories(baseDir);
}
}
//# sourceMappingURL=local.driver.js.map