diff --git a/helpers/error.js b/helpers/error.js new file mode 100644 index 0000000..a3dbcc7 --- /dev/null +++ b/helpers/error.js @@ -0,0 +1,24 @@ +const { logger } = require("../utils/logger"); +class ErrorHandler extends Error { + constructor(statusCode, message) { + super(); + this.status = "error"; + this.statusCode = statusCode; + this.message = message; + } +} + +const handleError = (err, req, res, next) => { + const { statusCode, message } = err; + logger.error(err); + res.status(statusCode || 500).json({ + status: "error", + statusCode: statusCode || 500, + message: statusCode === 500 ? "An error occurred" : message, + }); + next(); +}; +module.exports = { + ErrorHandler, + handleError, +}; diff --git a/helpers/hashPassword.js b/helpers/hashPassword.js new file mode 100644 index 0000000..c30a35a --- /dev/null +++ b/helpers/hashPassword.js @@ -0,0 +1,12 @@ +const bcrypt = require("bcrypt"); + +const hashPassword = async (password) => { + const salt = await bcrypt.genSalt(); + const hashedPassword = await bcrypt.hash(password, salt); + return hashedPassword; +}; + +const comparePassword = async (password, passwordHash) => + await bcrypt.compare(password, passwordHash); + +module.exports = { hashPassword, comparePassword }; diff --git a/helpers/test_helper.js b/helpers/test_helper.js new file mode 100644 index 0000000..95b8e28 --- /dev/null +++ b/helpers/test_helper.js @@ -0,0 +1,13 @@ +const pool = require("../config"); + +const usersInDb = async () => { + const users = await pool.query("SELECT * FROM USERS"); + return users.rows; +}; + +const productsInDb = async () => { + const products = await pool.query("SELECT * FROM products"); + return products.rows; +}; + +module.exports = { usersInDb, productsInDb }; diff --git a/helpers/utils.js b/helpers/utils.js new file mode 100644 index 0000000..41c60ed --- /dev/null +++ b/helpers/utils.js @@ -0,0 +1,89 @@ +const setResponse = async (data = [], message = "success", statusCode = 200) => { + const response = { + data, + total: data.length, + message, + statusCode + } + + return response +}; + +const setResponsePaging = async (data = [], total, limit, page, message = "success", statusCode = 200) => { + + const totalPages = Math.ceil(total / limit); + + const response = { + message, + statusCode, + data, + total: data.length, + paging: { + total, + limit, + page, + page_total: totalPages + } + } + + return response +}; + +const setPaging = async (total, limit, page) => { + + const totalPages = Math.ceil(total / limit); + + const response = { + total, + limit, + page, + page_total: totalPages + } + + return response +}; + +function convertId(items, id, fieldId = "id", fieldName = "name") { + var match = "" + items.forEach(element => { + if (element[fieldId] == id) { + match = element[fieldName] + } + }); + + return match +} + +function formatToYYYYMMDD(date) { + return new Intl.DateTimeFormat('id-ID', { + timeZone: 'Asia/Jakarta', + year: 'numeric', + month: '2-digit', + day: '2-digit', + }).format(date).split('/').reverse().join('-'); // Ubah format dari dd/mm/yyyy ke yyyy-mm-dd +} + +function ensureArray(param) { + return Array.isArray(param) ? param : [param]; +} + +function orderByClauseQuery(orderParams) { + orderParams = ensureArray(orderParams) + + // Transform order parameters to SQL ORDER BY syntax + const validDirections = ['ASC', 'DESC']; + const orderConditions = orderParams.map(param => { + const [field, direction] = param.split(':'); + if (!validDirections.includes(direction.toUpperCase())) { + throw new Error(`Invalid direction: ${direction}`); + } + return `${field} ${direction}`; + }); + + // Gabungkan dengan koma untuk digunakan dalam query + const orderByClause = orderConditions.join(', '); + + return orderByClause +} + +module.exports = { setResponse, setResponsePaging, setPaging, convertId, formatToYYYYMMDD, orderByClauseQuery }; diff --git a/helpers/validateUser.js b/helpers/validateUser.js new file mode 100644 index 0000000..c904bb4 --- /dev/null +++ b/helpers/validateUser.js @@ -0,0 +1,9 @@ +const validateUser = (email, password) => { + const validEmail = typeof email === "string" && email.trim() !== ""; + const validPassword = + typeof password === "string" && password.trim().length >= 6; + + return validEmail && validPassword; +}; + +module.exports = validateUser;