forked from idurar/idurar-erp-crm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request idurar#424 from Aman-Gupta-404/create-file-uploade…
…r-controller Creating New Generic File Upload Controller
- Loading branch information
Showing
6 changed files
with
769 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,62 @@ | ||
/* | ||
Catch Errors Handler | ||
With async/await, you need some way to catch errors | ||
Instead of using try{} catch(e) {} in each controller, we wrap the function in | ||
catchErrors(), catch any errors they throw, and pass it along to our express middleware with next() | ||
*/ | ||
|
||
exports.catchErrors = (fn) => { | ||
return function (req, res, next) { | ||
const resp = fn(req, res, next); | ||
if (resp instanceof Promise) { | ||
return resp.catch(next); | ||
} | ||
return resp; | ||
}; | ||
}; | ||
|
||
/* | ||
Not Found Error Handler | ||
If we hit a route that is not found, we mark it as 404 and pass it along to the next error handler to display | ||
*/ | ||
exports.notFound = (req, res, next) => { | ||
res.status(404).json({ | ||
success: false, | ||
message: "Api url doesn't exist ", | ||
}); | ||
}; | ||
|
||
/* | ||
Development Error Handler | ||
In development we show good error messages so if we hit a syntax error or any other previously un-handled error, we can show good info on what happened | ||
*/ | ||
exports.developmentErrors = (err, req, res, next) => { | ||
err.stack = err.stack || ''; | ||
const errorDetails = { | ||
message: err.message, | ||
status: err.status, | ||
stackHighlighted: err.stack.replace(/[a-z_-\d]+.js:\d+:\d+/gi, '<mark>$&</mark>'), | ||
}; | ||
|
||
res.status(500).json({ | ||
success: false, | ||
message: 'Oops ! Error in Server', | ||
error: err, | ||
}); | ||
}; | ||
|
||
/* | ||
Production Error Handler | ||
No stacktraces are leaked to admin | ||
*/ | ||
exports.productionErrors = (err, req, res, next) => { | ||
res.status(500).json({ | ||
success: false, | ||
message: 'Oops ! Error in Server', | ||
error: err, | ||
}); | ||
}; | ||
/* | ||
Catch Errors Handler | ||
With async/await, you need some way to catch errors | ||
Instead of using try{} catch(e) {} in each controller, we wrap the function in | ||
catchErrors(), catch any errors they throw, and pass it along to our express middleware with next() | ||
*/ | ||
|
||
exports.catchErrors = (fn) => { | ||
return function (req, res, next) { | ||
const resp = fn(req, res, next); | ||
if (resp instanceof Promise) { | ||
return resp.catch(next); | ||
} | ||
return resp; | ||
}; | ||
}; | ||
|
||
/* | ||
Not Found Error Handler | ||
If we hit a route that is not found, we mark it as 404 and pass it along to the next error handler to display | ||
*/ | ||
exports.notFound = (req, res, next) => { | ||
res.status(404).json({ | ||
success: false, | ||
message: "Api url doesn't exist ", | ||
}); | ||
}; | ||
|
||
/* | ||
Development Error Handler | ||
In development we show good error messages so if we hit a syntax error or any other previously un-handled error, we can show good info on what happened | ||
*/ | ||
exports.developmentErrors = (err, req, res, next) => { | ||
err.stack = err.stack || ''; | ||
const errorDetails = { | ||
message: err.message, | ||
status: err.status, | ||
stackHighlighted: err.stack.replace(/[a-z_-\d]+.js:\d+:\d+/gi, '<mark>$&</mark>'), | ||
}; | ||
|
||
res.status(500).json({ | ||
success: false, | ||
message: 'Oops ! Error in Server', | ||
error: err, | ||
}); | ||
}; | ||
|
||
/* | ||
Production Error Handler | ||
No stacktraces are leaked to admin | ||
*/ | ||
exports.productionErrors = (err, req, res, next) => { | ||
res.status(500).json({ | ||
success: false, | ||
message: 'Oops ! Error in Server', | ||
error: err, | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
const Upload = require('@/models/erpModels/Upload'); | ||
const multer = require('multer'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const { transliterate, slugify } = require('transliteration'); | ||
|
||
// middleware to upload the public document | ||
const createPublicUpload = async (req, res, next) => { | ||
const modelName = req.params.model; | ||
const fieldId = req.params.fieldId; | ||
const userID = req.admin._id; | ||
|
||
if (req?.upload?.files?.length !== 0) { | ||
let filesArr = req.upload.files; | ||
let _uploadsArray = []; | ||
|
||
filesArr.forEach((uploadItem) => { | ||
// creating the object for individual upload document | ||
let uploadObject = { | ||
modelName: modelName, | ||
fieldId: fieldId, | ||
fileName: uploadItem.fileName, | ||
fileType: uploadItem.fieldExt.slice(1), //removing the dot from the fileExt | ||
enabled: true, | ||
isPublic: true, | ||
userID: userID, | ||
isSecure: true, | ||
removed: false, | ||
path: `/upload/${modelName}/${uploadItem.fileName}${uploadItem.fieldExt}`, | ||
}; | ||
|
||
_uploadsArray.push(uploadObject); | ||
}); | ||
|
||
try { | ||
const upload = await Upload.insertMany(_uploadsArray); | ||
if (upload?.length !== 0) { | ||
next(); | ||
} else { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
} catch (error) { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
} else { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
}; | ||
|
||
// middleware to upload the private document | ||
const createPrivateUpload = async (req, res, next) => { | ||
const modelName = req.params.model; | ||
const fieldId = req.params.fieldId; | ||
const userID = req.admin._id; | ||
|
||
if (req?.upload?.files?.length !== 0) { | ||
let filesArr = req.upload.files; | ||
let _uploadsArray = []; | ||
|
||
filesArr.forEach((uploadItem) => { | ||
// creating the object for individual upload document | ||
let uploadObject = { | ||
modelName: modelName, | ||
fieldId: fieldId, | ||
fileName: uploadItem.fileName, | ||
fileType: uploadItem.fieldExt.slice(1), //removing the dot from the fileExt | ||
enabled: true, | ||
isPublic: false, | ||
userID: userID, | ||
isSecure: true, | ||
removed: false, | ||
path: `/upload/${modelName}/${uploadItem.fileName}${uploadItem.fieldExt}`, | ||
}; | ||
|
||
_uploadsArray.push(uploadObject); | ||
}); | ||
|
||
try { | ||
const upload = await Upload.insertMany(_uploadsArray); | ||
|
||
if (upload?.length !== 0) { | ||
next(); | ||
} else { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
} catch (error) { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
} else { | ||
return res.status(500).json({ success: false, message: 'Oops there is an Error' }); | ||
} | ||
}; | ||
|
||
const storage = multer.diskStorage({ | ||
//--> public/upload/:model/:fieldId. | ||
destination: function (req, file, cb) { | ||
const modelName = req.params.model; | ||
fs.mkdir(`upload/${modelName}`, (err) => { | ||
return cb(null, `upload/${modelName}`); | ||
}); | ||
}, | ||
filename: function (req, file, cb) { | ||
// fetching the file extention of the uploaded file | ||
let fileExtension = path.extname(file.originalname); | ||
let uniqueFileID = Math.random().toString(36).slice(2, 7); //generates unique ID of length 5 | ||
|
||
let originalname = slugify(file.originalname.split('.')[0].toLocaleLowerCase()); //convert any language to english characters | ||
let _fileName = `${originalname}-${uniqueFileID}${fileExtension}`; | ||
|
||
// saving file name and extention in request upload object | ||
let files = req?.upload?.files ?? []; | ||
const _data = { | ||
fileName: _fileName, | ||
fieldExt: fileExtension, | ||
}; | ||
files.push(_data); | ||
req.upload = { | ||
files: files, | ||
}; | ||
return cb(null, _fileName); | ||
}, | ||
}); | ||
|
||
const fileFilter = (req, file, cb) => { | ||
// array containing all the possible file types | ||
const _fileType = [ | ||
'image/jpeg', | ||
'image/png', | ||
'image/gif', | ||
'image/webp', | ||
'application/msword', | ||
'text/plain', | ||
'text/csv', | ||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', | ||
'application/vnd.ms-excel', | ||
'application/pdf', | ||
'application/zip', | ||
'application/vnd.rar', | ||
'video/mp4', | ||
'video/x-msvideo', | ||
'audio/mpeg', | ||
'video/webm', | ||
]; | ||
|
||
let _flag = _fileType.includes(file.mimetype); | ||
|
||
if (_flag) { | ||
return cb(null, true); | ||
} else { | ||
return cb(new Error(`${file.mimetype} File type not supported!`)); | ||
} | ||
}; | ||
|
||
const uploadMiddleware = multer({ storage: storage, fileFilter: fileFilter }); | ||
|
||
module.exports = { createPublicUpload, createPrivateUpload, uploadMiddleware }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
const mongoose = require('mongoose'); | ||
mongoose.Promise = global.Promise; | ||
|
||
const uploadSchema = new mongoose.Schema({ | ||
modelName: { | ||
type: String, | ||
trim: true, | ||
}, | ||
fieldId: { | ||
type: String, | ||
required: true, | ||
}, | ||
fileName: { | ||
type: String, | ||
required: true, | ||
}, | ||
fileType: { | ||
type: String, | ||
enum: [ | ||
'jpeg', | ||
'jpg', | ||
'png', | ||
'gif', | ||
'webp', | ||
'doc', | ||
'txt', | ||
'csv', | ||
'docx', | ||
'xls', | ||
'xlsx', | ||
'pdf', | ||
'zip', | ||
'rar', | ||
'mp4', | ||
'mov', | ||
'avi', | ||
'mp3', | ||
'm4a', | ||
'webm', | ||
], | ||
required: true, | ||
}, | ||
enabled: { | ||
type: Boolean, | ||
default: true, | ||
}, | ||
isPublic: { | ||
type: Boolean, | ||
required: true, | ||
}, | ||
userID: { | ||
type: mongoose.SchemaTypes.ObjectId, | ||
required: true, | ||
}, | ||
isSecure: { | ||
type: Boolean, | ||
required: true, | ||
}, | ||
removed: { | ||
type: Boolean, | ||
default: false, | ||
required: true, | ||
}, | ||
path: { | ||
type: String, | ||
unique: true, | ||
required: true, | ||
}, | ||
}); | ||
|
||
module.exports = mongoose.model('Upload ', uploadSchema); |
Oops, something went wrong.