ADD: SignedUrls for documents, mainImage and images

ADD: Bucket and Upload System
ADD: New errors
ADD: Virtuals for categories
ADD: Features system
ADD: File management system
This commit is contained in:
2025-01-04 22:06:43 +03:30
parent 9e342cbc57
commit 2d87cc4834
21 changed files with 2100 additions and 77 deletions
+103
View File
@@ -0,0 +1,103 @@
const catchAsync = require('../../globalErrorHandler/catchAsync')
const fileService = require('./fileService')
exports.bucketSingleUpload = catchAsync(async (req, res, next) => {
const fileData = await fileService.bucketSingleUpload(req.file, req.params.bucketName)
res.status(200).json({
status: 'success',
data: fileData,
})
})
exports.userUploadOrderDocument = catchAsync(async (req, res, next) => {
const files = await fileService.userUploadOrderDocument(req.files)
res.status(200).json({
status: 'success',
results: files.length,
data: files,
})
})
exports.bucketMultiUpload = catchAsync(async (req, res, next) => {
const files = await fileService.bucketMultiUpload(req.files, req.params.bucketName)
res.status(200).json({
status: 'success',
results: files.length,
data: files,
})
})
exports.bucketGetFiles = catchAsync(async (req, res, next) => {
const files = await fileService.bucketGetFiles()
res.status(200).json({
status: 'success',
results: files.length,
data: files,
})
})
exports.getSignedUrl = catchAsync(async (req, res, next) => {
const url = await fileService.getSignedUrl(req.body.fileName)
res.status(200).json({
status: 'success',
data: url,
})
})
exports.bucketDeleteFile = catchAsync(async (req, res, next) => {
await fileService.bucketDeleteFile(req.body, req.params.bucketName)
res.status(200).json({
status: 'success',
})
})
exports.getAllFiles = catchAsync(async (req, res, next) => {
const files = await fileService.getAllFiles()
res.status(200).json({
status: 'success',
results: files.length,
data: files,
})
})
exports.getFile = catchAsync(async (req, res, next) => {
const file = await fileService.getFile(req.body.id)
res.status(200).json({
status: 'success',
data: file,
})
})
exports.createFile = catchAsync(async (req, res, next) => {
const file = await fileService.createFile(req.body)
res.status(201).json({
status: 'success',
data: file,
})
})
exports.updateFile = catchAsync(async (req, res, next) => {
const file = await fileService.updateFile(req.body)
res.status(200).json({
status: 'success',
data: file,
})
})
exports.deleteFile = catchAsync(async (req, res, next) => {
await fileService.deleteFile(req.body.id)
res.status(204).json({
status: 'success',
data: null,
})
})
+32
View File
@@ -0,0 +1,32 @@
const mongoose = require('mongoose')
const ObjectID = mongoose.Schema.Types.ObjectId
const fileSchema = new mongoose.Schema(
{
fileName: {
type: String,
required: true,
},
owner: {
type: ObjectID,
ref: 'User',
},
fileEndpoint: String,
bucketName: {
type: String,
required: true,
},
},
{
toJSON: { virtuals: true },
toObject: { virtuals: true },
},
{ timestamps: true }
)
fileSchema.virtual('publicUrl').get(function () {
return this.fileEndpoint + '/' + this.bucketName + '/' + this.fileName
})
const File = mongoose.model('file', fileSchema)
module.exports = File
+50
View File
@@ -0,0 +1,50 @@
const express = require('express')
const fileController = require('./fileController')
const perm = require('../../middlewares/permissionMiddleware')
const loginCheck = require('../../middlewares/loginCheck')
const upload = require('../../middlewares/multerMiddleware')
const router = new express.Router()
router.use(loginCheck.loginProtect)
router.post(
'/bucket/upload-single/:bucketName/',
perm.requires('uploadsinglefile'),
upload.single('image'),
fileController.bucketSingleUpload
)
router.post(
'/bucket/upload-single-filepond/:bucketName',
perm.requires('uploadsinglefile'),
upload.single('filepond-image'),
fileController.bucketSingleUpload
)
router.post('/bucket/upload-multi', perm.requires('uploadmultifile'), upload.array('image', 100), fileController.bucketMultiUpload)
router.post(
'/bucket/upload-multi-filepond/:bucketName',
perm.requires('uploadmultifile'),
upload.array('filepond-image', 100),
fileController.bucketMultiUpload
)
router.get('/bucket/get-files', perm.requires('getbucketfiles'), fileController.bucketGetFiles)
router.get('/bucket/get-signed', perm.requires('getbucketfiles'), fileController.getSignedUrl)
router.delete('/bucket/delete-file/:bucketName', perm.requires('deletebucketfiles'), fileController.bucketDeleteFile)
router.get('/admin/get-all', perm.requires('getallfiles'), fileController.getAllFiles)
router.post('/admin/create', perm.requires('createfile'), fileController.createFile)
router.get('/admin/get-one/:fileId', perm.requires('getfile'), fileController.getFile)
router.put('/admin/update/:fileId', perm.requires('updatefile'), fileController.updateFile)
router.delete('/admin/delete/:fileId', perm.requires('deletefile'), fileController.deleteFile)
module.exports = router
+136
View File
@@ -0,0 +1,136 @@
const File = require('./fileModel')
const AppError = require('../../globalErrorHandler/AppError')
const util = require('util')
const fs = require('fs')
const {
uploadObject,
deleteObject,
listOfObjects,
signedUrl,
copyObject,
removeObject,
} = require('../../utils/upload/bucket')
const deleteTempFile = util.promisify(fs.unlink)
const bucketSingleUpload = async (file, bucketName) => {
const fileData = {
originalName: file.originalname,
filename: file.filename,
path: file.path,
}
const result = await uploadObject(fileData, bucketName)
const data = {
fileURL: result.fileURL,
fileName: result.fileName,
fileEndpoint: result.fileEndpoint,
bucketName,
}
// Delete file from uploads folder
await deleteTempFile(file.path)
const fileRecord = await createFile(data)
return {
status: 'success',
fileRecord,
}
}
const bucketMultiUpload = async (files, bucketName) => {
const results = []
for (let file of files) {
const result = await bucketSingleUpload(file, bucketName)
results.push(result)
}
return results
}
const bucketDeleteFile = async (fileName, bucketName) => {
await deleteObject(fileName, bucketName)
await deleteFile(fileName)
return null
}
const getAllFiles = async () => {
return File.find({}, null, null)
}
const getFile = async (fileId) => {
const file = await File.findById(fileId, null, null)
if (!file) {
throw new AppError('NoFileFound', 404, {})
}
return file
}
const createFile = async (data) => {
return File.create(data, null)
}
const updateFile = async (fileId, data) => {
const file = await File.findOneAndUpdate({ _id: fileId }, data, null)
if (!file) {
throw AppError('NoFileFound', 404, {})
}
return file
}
const deleteFile = async (fileName) => {
await File.findOneAndDelete({ fileName }, null)
return null
}
const bucketGetFiles = async (bucketName) => {
return listOfObjects(bucketName)
}
const getSignedUrl = async (fileName, bucketName) => {
if (!fileName) {
return
}
return signedUrl(bucketName, fileName)
}
const getMultipleSignedUrls = async (fileNameArray, bucketName) => {
const urls = []
for (let fileName of fileNameArray) {
urls.push({ url: await getSignedUrl(fileName, bucketName)})
}
return urls
}
const moveFromTempToMain = async (files, targetBucket) => {
const tempBucket = 'temp'
for (const file of files) {
await copyObject(targetBucket, file, `${tempBucket}/${file}`)
await removeObject(tempBucket, file)
}
}
module.exports = {
moveFromTempToMain,
getMultipleSignedUrls,
getSignedUrl,
createFile,
updateFile,
deleteFile,
getAllFiles,
getFile,
bucketSingleUpload,
bucketMultiUpload,
bucketDeleteFile,
bucketGetFiles,
}