import fs from 'node:fs'; import path from 'node:path'; import multer from 'multer'; import { nanoid } from 'nanoid'; import { config } from '../config.js'; const incomingDir = path.join(config.fileLockerDir, '_incoming'); fs.mkdirSync(incomingDir, { recursive: true }); function sanitizeFileName(name) { return String(name || 'asset.bin') .replace(/[/\\?%*:|"<>]/g, '-') .replace(/\s+/g, ' ') .trim() .slice(0, 180) || 'asset.bin'; } const storage = multer.diskStorage({ destination(req, file, callback) { fs.mkdirSync(incomingDir, { recursive: true }); callback(null, incomingDir); }, filename(req, file, callback) { callback(null, `${Date.now()}-${nanoid(8)}-${sanitizeFileName(file.originalname)}`); } }); // Asset uploads are staged in FileLocker before the model promotes them into the typed library tree. export const assetUpload = multer({ storage, limits: { fileSize: config.maxAssetBytes } });