Reputation: 126
Hello I am trying to select the storage at runtime , because I also added a middleware for getting the content-size just before .
I have an exported enum elsewhere :
export enum Storage {
DISK,
MEMORY
}
Middleware checkHeader :
const checkHeader = (req :any , res: any , next:any ) => {
console.log('content-length :',req.headers['content-length']);
const sizeContent = req.headers['content-length'];
if (!sizeContent || Number(sizeContent) ==0 ) {
res.send(400).end();
return;
}
const sizeKo = Number(sizeContent)/1024 >5000 ;
console.log('size : (KO) ',sizeKo);
res.locals.storage = Number(sizeContent)/1024 >5000 ? Storage.DISK:Storage.MEMORY;
next();
};
make multer middleware
const createUpload = (_req: Request, res: Response, _next:any) :any =>{
let storage;
if (res.locals) {console.log('in createupload : ' , res.locals.storage);}
else return _next;
if (res.locals.storage === Storage.DISK){
storage = multer.diskStorage({
destination: function (_req, _file, cb) {
cb(null, './uploads/');
},
filename: function (_req: any, file: any, cb: any) {
cb(null, file.originalname);
},
});
}
else {
storage = multer.memoryStorage();
}
return multer({ storage: storage, fileFilter: fileFilter }).any();
};
create route
const router = express
.Router()
.get('/', controller.all)
.post('/', controller.create)
.get('/:id', controller.byId)
.get('/:id/contractors', controller.getContractors)
.post('/:id/contractors', controller.addContractors)
.post('/:id/documents', checkHeader ,createUpload, controller.addDocument);
It doesn't work , I suppose it is because createUpload doesn't return , i.e, an example ,
multer({storage : multer.memoryStorage()}).any()
but it returns the function that return it !!
But I am forced to write it as a middleware function, i.e (req,res,next)=>return
a middleware, in order to get it pass through the middleware chain ....
I don't know how to write the code for this use case , ...
Thank in advance
Upvotes: 0
Views: 599
Reputation: 126
Finally , I got a workaround :
const fileFilter = (_req: any, file: any, cb: any) => {
if (
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg' ||
file.mimetype === 'image/png' ||
file.mimetype === 'application/pdf'
) {
cb(null, true);
} else {
cb(new Error('not type pdf or jpg/jpeg or png'), false);
}
};
const setUploadDest = (req :any , res: any , next:any ) => {
console.log('content-length :',req.headers['content-length']);
const sizeContent = req.headers['content-length'];
res.locals.storage = Number(sizeContent)/1024 >5000 ? Storage.DISK:Storage.MEMORY;
next();
};
const skipMemory = (_req :any , res: any , next:any ) => {
if (res.locals.storage !== Storage.MEMORY){
next('route');
}
else next();
};
const skipDisk = (_req :any , res: any , next:any ) => {
if (res.locals.storage !== Storage.DISK){
next('route');
}
else next();
};
const diskStorage = multer.diskStorage({
destination: function (_req, _file, cb) {
cb(null, './uploads/');
},
filename: function (_req: any, file: any, cb: any) {
cb(null, file.originalname);
}
});
const router = express
.Router()
.get('/', controller.all)
.post('/', controller.create)
.get('/:id', controller.byId)
.get('/:id/contractors', controller.getContractors)
.post('/:id/contractors', controller.addContractors)
.use('/:id/documents',setUploadDest)
.post('/:id/documents', skipMemory , multer({storage : multer.memoryStorage(), fileFilter:fileFilter}).any() , controller.addDocument)
.post('/:id/documents', skipDisk, multer({storage : diskStorage, fileFilter :fileFilter}).any() , controller.addDocument);
means I duplicated the post Router , one each is attached to a multer storage constructor . I control the routes by adding a "skip" middleware which gonna send to an other route if storage condtion not met ...
Upvotes: 1