UNPKG

@browser.style/asset-server

Version:
101 lines (86 loc) 3 kB
import multer from 'multer'; import path from 'path'; import fs from 'fs'; // Helper function to get asset directory path (similar to controller) function getAssetDirectoryPath(sku) { const chunkedPath = []; // Process SKU in chunks of 2 characters for (let i = 0; i < sku.length; i += 2) { if (i + 2 <= sku.length) { chunkedPath.push(sku.substring(i, i + 2)); } else if (i < sku.length) { chunkedPath.push(sku.substring(i) + '0'); } } // If SKU is too short, pad with leading directories while (chunkedPath.length > 0 && chunkedPath.length < 3) { chunkedPath.unshift('00'); } // Add the full SKU as the final directory const dirPath = [...chunkedPath, sku]; return path.join('assets', ...dirPath); } // Custom storage strategy const storage = multer.diskStorage({ destination: function (req, file, cb) { try { // Get product ID from parameters const { id } = req.params; const dir = path.join(process.cwd(), getAssetDirectoryPath(id)); // Create directory if it doesn't exist fs.mkdirSync(dir, { recursive: true }); cb(null, dir); } catch (error) { cb(error); } }, filename: function (req, file, cb) { try { // Get product ID from parameters const { id } = req.params; const dir = path.join(process.cwd(), getAssetDirectoryPath(id)); // Extract original filename and extension const originalName = path.parse(file.originalname).name; const extension = path.extname(file.originalname); // Check if a file with the same name already exists const originalFullPath = path.join(dir, `${originalName}${extension}`); if (fs.existsSync(originalFullPath)) { // If file exists, add timestamp and random number to ensure uniqueness const timestamp = Date.now(); const randomNum = Math.floor(Math.random() * 1000000000); const newFilename = `${originalName}-${timestamp}-${randomNum}${extension}`; cb(null, newFilename); } else { // If file doesn't exist, use original name cb(null, `${originalName}${extension}`); } } catch (error) { cb(error); } } }); // File filter to validate file types const fileFilter = (req, file, cb) => { // Get allowed types from query parameters or environment variable const allowedTypes = process.env.ALLOWED_TYPES ? process.env.ALLOWED_TYPES.split(',') : ['image/jpeg', 'image/png', 'image/gif', 'application/pdf']; if (allowedTypes.includes(file.mimetype)) { cb(null, true); } else { cb(new Error(`File type ${file.mimetype} is not allowed`), false); } }; // Configure multer export const upload = multer({ storage: storage, fileFilter: fileFilter, limits: { fileSize: parseInt(process.env.MAX_FILE_SIZE || '10') * 1024 * 1024 // Default 10MB } }); // Export file-related utilities export default { upload, getAssetDirectoryPath };