refactor: rewrite ke codebase lama
This commit is contained in:
Executable
+7
@@ -0,0 +1,7 @@
|
||||
const { PrismaClient } = require('../../generated/prisma');
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
log: ['query', 'info', 'warn', 'error'],
|
||||
});
|
||||
|
||||
module.exports = prisma
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
const { PrismaClient } = require("generated/prisma/index.js");
|
||||
|
||||
const prisma = new PrismaClient({
|
||||
log: [
|
||||
{
|
||||
emit: 'event',
|
||||
level: 'query',
|
||||
},
|
||||
{
|
||||
emit: 'stdout',
|
||||
level: 'error',
|
||||
},
|
||||
{
|
||||
emit: 'stdout',
|
||||
level: 'info',
|
||||
},
|
||||
{
|
||||
emit: 'stdout',
|
||||
level: 'warn',
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
module.exports = { prisma };
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class BadRequestError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Bad Request');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BadRequestError;
|
||||
Executable
+7
@@ -0,0 +1,7 @@
|
||||
class CommonError extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CommonError;
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class ConflictError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Conflict');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConflictError;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class ExpectationFailedError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Expectation Failed');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ExpectationFailedError;
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class ForbiddenError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Forbidden');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ForbiddenError;
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class GatewayTimeoutError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Gateway Timeout');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GatewayTimeoutError;
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
const ConflictError = require('./conflict_error');
|
||||
const ExpectationFailedError = require('./expectation_failed_error');
|
||||
const ForbiddenError = require('./forbidden_error');
|
||||
const InternalServerError = require('./internal_server_error');
|
||||
const NotFoundError = require('./not_found_error');
|
||||
const UnauthorizedError = require('./unauthorized_error');
|
||||
const ServiceUnavailableError = require('./service_unavailable_error');
|
||||
const GatewayTimeoutError = require('./gateway_timeout_error');
|
||||
const BadRequestError = require('./bad_request_error');
|
||||
const ValidationError = require('./validation_error');
|
||||
|
||||
module.exports = {
|
||||
ConflictError,
|
||||
ExpectationFailedError,
|
||||
ForbiddenError,
|
||||
InternalServerError,
|
||||
NotFoundError,
|
||||
UnauthorizedError,
|
||||
ServiceUnavailableError,
|
||||
GatewayTimeoutError,
|
||||
BadRequestError,
|
||||
ValidationError
|
||||
};
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class InternalServerError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Internal Server Error');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = InternalServerError;
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class NotFoundError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Not Found');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = NotFoundError;
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class ServiceUnavailableError extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Service Unavailable');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServiceUnavailableError;
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
const CommonError = require('./common_error');
|
||||
|
||||
class Unauthorized extends CommonError {
|
||||
constructor(message) {
|
||||
super(message || 'Unauthorized');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Unauthorized;
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
class ValidationError extends Error {
|
||||
constructor(message, errors) {
|
||||
super(message || 'Validation Error');
|
||||
this.errors = errors
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ValidationError;
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
const ERROR = {
|
||||
'BAD_REQUEST': 400,
|
||||
'NOT_FOUND': 404,
|
||||
'INTERNAL_ERROR': 500,
|
||||
'CONFLICT': 409,
|
||||
'EXPECTATION_FAILED': 417,
|
||||
'FORBIDDEN': 403,
|
||||
'UNAUTHORIZED': 401,
|
||||
'SERVICE_UNAVAILABLE': 503,
|
||||
'GATEWAY_TIMEOUT': 504
|
||||
};
|
||||
|
||||
const SUCCESS = {
|
||||
'OK': 200,
|
||||
'CREATED': 201
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
ERROR,
|
||||
SUCCESS
|
||||
};
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
const dotnev = require('dotenv');
|
||||
|
||||
dotnev.config({ path: '.env' })
|
||||
|
||||
const config = {
|
||||
port: process.env.EXPRESS_PORT,
|
||||
jwtPrivateKey: process.env.JWT_PRIVATE_KEY,
|
||||
jwtPublicKey: process.env.JWT_PUBLIC_KEY,
|
||||
nodeEnv: process.env.NODE_ENV,
|
||||
mysqlConfig: {
|
||||
host: process.env.MYSQL_HOST,
|
||||
user: process.env.MYSQL_USER,
|
||||
password: process.env.MYSQL_PASSWORD,
|
||||
database: process.env.MYSQL_DATABASE,
|
||||
dialect: 'mysql',
|
||||
logging: false
|
||||
},
|
||||
nodemailerConfig: {
|
||||
email: process.env.NODEMAILER_EMAIL,
|
||||
password: process.env.NODEMAILER_PASSWORD
|
||||
},
|
||||
cloudinaryConfig: {
|
||||
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
|
||||
api_key: process.env.CLOUDINARY_API_KEY,
|
||||
api_secret: process.env.CLOUDINARY_API_SECRET,
|
||||
secure: true
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = { config };
|
||||
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