Disk-based multer plus an authenticated content endpoint match the working Node.js uploader and avoid browser signed-URL failures on SeaweedFS.
61 lines
2.0 KiB
JavaScript
61 lines
2.0 KiB
JavaScript
// /components/files/fileController.js
|
|
|
|
const catchAsync = require('../../utils/catchAsync');
|
|
const fileService = require('./fileService');
|
|
const { successResponse } = require('../../utils/apiResponse');
|
|
const AppError = require('../../utils/AppError');
|
|
|
|
const pickUploadedFile = (req) => {
|
|
if (req.file) return req.file;
|
|
if (Array.isArray(req.files) && req.files.length) return req.files[0];
|
|
if (req.files && typeof req.files === 'object') {
|
|
return req.files.file?.[0]
|
|
|| req.files['filepond-image']?.[0]
|
|
|| Object.values(req.files).flat().find(Boolean)
|
|
|| null;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
exports.uploadTemp = catchAsync(async (req, res, next) => {
|
|
const uploaded = pickUploadedFile(req);
|
|
if (!uploaded) {
|
|
return next(new AppError('FILE_REQUIRED'));
|
|
}
|
|
|
|
const result = await fileService.uploadTempFile(uploaded);
|
|
|
|
// 200 matches the working FilePond Node.js uploader (2xx is required)
|
|
return successResponse(res, 200, 'File uploaded to temp bucket successfully', result);
|
|
});
|
|
|
|
exports.getSignedUrl = catchAsync(async (req, res, next) => {
|
|
const { filename } = req.params;
|
|
const { bucket } = req.query;
|
|
|
|
const result = await fileService.getPresignedUrl(filename, bucket);
|
|
return successResponse(res, 200, 'Temporary presigned URL generated successfully', result);
|
|
});
|
|
|
|
exports.streamFile = catchAsync(async (req, res, next) => {
|
|
const key = req.query.key || req.params.filename;
|
|
const bucket = req.query.bucket;
|
|
|
|
if (!key) {
|
|
return next(new AppError('VALIDATION_FAILED', null, 'Filename is required'));
|
|
}
|
|
|
|
const { buffer, contentType } = await fileService.getFileContent(key, bucket);
|
|
res.set('Content-Type', contentType);
|
|
res.set('Cache-Control', 'private, max-age=60');
|
|
return res.status(200).send(buffer);
|
|
});
|
|
|
|
exports.deleteFile = catchAsync(async (req, res, next) => {
|
|
const { filename } = req.params;
|
|
const { bucket } = req.query;
|
|
|
|
await fileService.deleteFile(filename, bucket);
|
|
return successResponse(res, 200, 'File deleted successfully');
|
|
});
|