refactor: rewrite ke codebase lama
This commit is contained in:
Executable
+53
@@ -0,0 +1,53 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs').promises;
|
||||
const fsSync = require('fs');
|
||||
|
||||
async function deleteFileIfExists(fileName) {
|
||||
try {
|
||||
const uploadDir = process.env.NODE_ENV === 'production'
|
||||
? '/tmp/uploads'
|
||||
: path.join(__dirname, '..', '..', 'uploads');
|
||||
|
||||
const fullPath = path.join(uploadDir, fileName);
|
||||
await fs.access(fullPath);
|
||||
await fs.unlink(fullPath);
|
||||
console.log(`File dihapus: ${fullPath}`);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.warn(`File tidak ditemukan: ${fileName}`);
|
||||
} else {
|
||||
console.error(`Gagal menghapus file (${fileName}):`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkFileExists(filePath) {
|
||||
try {
|
||||
if (!filePath) return false;
|
||||
|
||||
const uploadDir = process.env.NODE_ENV === 'production'
|
||||
? '/tmp/uploads'
|
||||
: path.join(__dirname, '..', '..', 'uploads');
|
||||
|
||||
const fileName = path.basename(filePath);
|
||||
const fullPath = path.join(uploadDir, fileName);
|
||||
|
||||
return fsSync.existsSync(fullPath);
|
||||
} catch (err) {
|
||||
console.error(`Error checking file existence: ${err.message}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function validateImagePath(imagePath) {
|
||||
if (!imagePath) return null;
|
||||
|
||||
const fileExists = checkFileExists(imagePath);
|
||||
return fileExists ? imagePath : null;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
deleteFileIfExists,
|
||||
checkFileExists,
|
||||
validateImagePath
|
||||
};
|
||||
Executable
+57
@@ -0,0 +1,57 @@
|
||||
const { BadRequestError } = require('../error');
|
||||
|
||||
class ImageUploadHelper {
|
||||
uploadImage(file) {
|
||||
if (!file) {
|
||||
throw new BadRequestError('Please upload an image!');
|
||||
}
|
||||
return `/uploads/${file.filename}`;
|
||||
}
|
||||
|
||||
uploadCV(file) {
|
||||
if (!file) {
|
||||
throw new BadRequestError('Please upload your CV');
|
||||
}
|
||||
return `/uploads/${file.filename}`;
|
||||
}
|
||||
|
||||
uploadPortofolio(file) {
|
||||
if (!file) {
|
||||
throw new BadRequestError('Please upload your portfolio');
|
||||
}
|
||||
return `/uploads/${file.filename}`;
|
||||
}
|
||||
|
||||
validateImage(file) {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const allowedTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/webp'];
|
||||
return allowedTypes.includes(file.mimetype);
|
||||
}
|
||||
|
||||
validatePDF(file) {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const allowedTypes = ['application/pdf'];
|
||||
return allowedTypes.includes(file.mimetype);
|
||||
}
|
||||
|
||||
validateDocument(file) {
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const allowedTypes = [
|
||||
'application/pdf',
|
||||
'application/msword',
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
||||
];
|
||||
return allowedTypes.includes(file.mimetype);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new ImageUploadHelper();
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
require('dotenv').config();
|
||||
const nodemailer = require('nodemailer');
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
service: 'gmail',
|
||||
auth: {
|
||||
user: process.env.AUTH_EMAIL,
|
||||
pass: process.env.AUTH_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
||||
transporter.verify((error) => {
|
||||
if (error) {
|
||||
console.log('Error setup email:', error);
|
||||
} else {
|
||||
console.log('Server siap mengirim email');
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = transporter;
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
const wrapper = require('./wrapper');
|
||||
const { ValidationError } = require('../error');
|
||||
|
||||
const isValidPayload = (payload, model) => {
|
||||
const { value, error } = model.validate(payload, {
|
||||
abortEarly: false,
|
||||
allowUnknown: true,
|
||||
stripUnknown: true,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
let errors = {};
|
||||
error.details.forEach(element => {
|
||||
errors[element.path[0]] = element.message;
|
||||
});
|
||||
|
||||
return wrapper.error(new ValidationError('Validation Error', errors));
|
||||
}
|
||||
|
||||
return { err: null, data: value };
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
isValidPayload,
|
||||
};
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
const {
|
||||
NotFoundError,
|
||||
InternalServerError,
|
||||
BadRequestError,
|
||||
ConflictError,
|
||||
ExpectationFailedError,
|
||||
ForbiddenError,
|
||||
GatewayTimeoutError,
|
||||
ServiceUnavailableError,
|
||||
UnauthorizedError,
|
||||
ValidationError
|
||||
} = require('../error');
|
||||
const { ERROR: httpError } = require('../http-status/status_code');
|
||||
|
||||
const response = (res, type, result, message = '', code = 200) => {
|
||||
let status = true;
|
||||
let data = result?.data ?? null;
|
||||
|
||||
if (type === 'fail') {
|
||||
status = false;
|
||||
data = null;
|
||||
message = result.err instanceof ValidationError ? result.err.errors : result.err?.message || message;
|
||||
code = checkErrorCode(result.err);
|
||||
}
|
||||
|
||||
res.status(code).json({
|
||||
status,
|
||||
data,
|
||||
message,
|
||||
code,
|
||||
});
|
||||
};
|
||||
|
||||
const paginationResponse = (res, type, result, message = '', code = 200) => {
|
||||
let status = true;
|
||||
let data = result?.data ?? null;
|
||||
let meta = result?.meta ?? null;
|
||||
if (type === 'fail') {
|
||||
status = false;
|
||||
data = '';
|
||||
message = result.err instanceof ValidationError ? { errors: result.err.errors } : result.err?.message || message;
|
||||
code = checkErrorCode(result.err);
|
||||
}
|
||||
|
||||
console.log(typeof message)
|
||||
|
||||
res.status(code).json({
|
||||
status: status,
|
||||
data,
|
||||
meta,
|
||||
message,
|
||||
code,
|
||||
});
|
||||
}
|
||||
|
||||
const checkErrorCode = (error) => {
|
||||
switch (error.constructor) {
|
||||
case BadRequestError:
|
||||
return httpError.BAD_REQUEST;
|
||||
case ConflictError:
|
||||
return httpError.CONFLICT;
|
||||
case ExpectationFailedError:
|
||||
return httpError.EXPECTATION_FAILED;
|
||||
case ForbiddenError:
|
||||
return httpError.FORBIDDEN;
|
||||
case GatewayTimeoutError:
|
||||
return httpError.GATEWAY_TIMEOUT;
|
||||
case InternalServerError:
|
||||
return httpError.INTERNAL_ERROR;
|
||||
case NotFoundError:
|
||||
return httpError.NOT_FOUND;
|
||||
case ServiceUnavailableError:
|
||||
return httpError.SERVICE_UNAVAILABLE;
|
||||
case UnauthorizedError:
|
||||
return httpError.UNAUTHORIZED;
|
||||
case ValidationError:
|
||||
return httpError.BAD_REQUEST;
|
||||
default:
|
||||
return httpError.INTERNAL_ERROR;
|
||||
}
|
||||
};
|
||||
|
||||
const data = (data) => ({ err: null, data });
|
||||
|
||||
const paginationData = (data, meta) => ({ err: null, data, meta });
|
||||
|
||||
const error = (err) => ({ err, data: null });
|
||||
|
||||
module.exports = {
|
||||
data,
|
||||
paginationData,
|
||||
error,
|
||||
response,
|
||||
paginationResponse
|
||||
};
|
||||
Reference in New Issue
Block a user