Files
hMarket/backend/src/utils/helpers.js

379 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const crypto = require('crypto');
const jwt = require('jsonwebtoken');
/**
* Sayfalama hesaplamaları
* @param {number} page - Sayfa numarası
* @param {number} limit - Sayfa başına öğe sayısı
* @returns {object} Skip ve take değerleri
*/
const calculatePagination = (page = 1, limit = 10) => {
const pageNum = Math.max(1, parseInt(page));
const limitNum = Math.min(100, Math.max(1, parseInt(limit)));
return {
skip: (pageNum - 1) * limitNum,
take: limitNum,
page: pageNum,
limit: limitNum
};
};
/**
* Sayfalama meta bilgilerini oluştur
* @param {number} total - Toplam öğe sayısı
* @param {number} page - Mevcut sayfa
* @param {number} limit - Sayfa başına öğe sayısı
* @returns {object} Meta bilgileri
*/
const createPaginationMeta = (total, page, limit) => {
const totalPages = Math.ceil(total / limit);
return {
total,
page,
limit,
totalPages,
hasNext: page < totalPages,
hasPrev: page > 1
};
};
/**
* API yanıt formatı
* @param {boolean} success - İşlem başarılı mı
* @param {string} message - Mesaj
* @param {any} data - Veri
* @param {object} meta - Meta bilgileri
* @returns {object} Formatlanmış yanıt
*/
const createResponse = (success, message, data = null, meta = null) => {
const response = {
success,
message,
timestamp: new Date().toISOString()
};
if (data !== null) {
response.data = data;
}
if (meta !== null) {
response.meta = meta;
}
return response;
};
/**
* Başarılı yanıt oluştur
* @param {string} message - Mesaj
* @param {any} data - Veri
* @param {object} meta - Meta bilgileri
* @returns {object} Başarılı yanıt
*/
const successResponse = (message, data = null, meta = null) => {
return createResponse(true, message, data, meta);
};
/**
* Hata yanıtı oluştur
* @param {string} message - Hata mesajı
* @param {any} data - Hata detayları
* @returns {object} Hata yanıtı
*/
const errorResponse = (message, data = null) => {
return createResponse(false, message, data);
};
/**
* JWT token oluştur
* @param {object} payload - Token içeriği
* @param {string} expiresIn - Geçerlilik süresi
* @returns {string} JWT token
*/
const generateToken = (payload, expiresIn = process.env.JWT_EXPIRES_IN || '7d') => {
return jwt.sign(payload, process.env.JWT_SECRET, { expiresIn });
};
/**
* JWT token doğrula
* @param {string} token - JWT token
* @returns {object} Decoded token
*/
const verifyToken = (token) => {
return jwt.verify(token, process.env.JWT_SECRET);
};
/**
* Rastgele string oluştur
* @param {number} length - String uzunluğu
* @returns {string} Rastgele string
*/
const generateRandomString = (length = 32) => {
return crypto.randomBytes(length).toString('hex');
};
/**
* Güvenli karşılaştırma
* @param {string} a - İlk string
* @param {string} b - İkinci string
* @returns {boolean} Eşit mi
*/
const safeCompare = (a, b) => {
if (a.length !== b.length) {
return false;
}
return crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b));
};
/**
* Slug oluştur
* @param {string} text - Metin
* @returns {string} Slug
*/
const createSlug = (text) => {
return text
.toLowerCase()
.replace(/ç/g, 'c')
.replace(/ğ/g, 'g')
.replace(/ı/g, 'i')
.replace(/ö/g, 'o')
.replace(/ş/g, 's')
.replace(/ü/g, 'u')
.replace(/[^a-z0-9\s-]/g, '')
.replace(/\s+/g, '-')
.replace(/-+/g, '-')
.trim('-');
};
/**
* Tarih formatla
* @param {Date} date - Tarih
* @param {string} locale - Dil kodu
* @returns {string} Formatlanmış tarih
*/
const formatDate = (date, locale = 'tr-TR') => {
return new Intl.DateTimeFormat(locale, {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit'
}).format(new Date(date));
};
/**
* Fiyat formatla
* @param {number} price - Fiyat
* @param {string} currency - Para birimi
* @returns {string} Formatlanmış fiyat
*/
const formatPrice = (price, currency = 'TRY') => {
return new Intl.NumberFormat('tr-TR', {
style: 'currency',
currency: currency
}).format(price);
};
/**
* Dosya boyutu formatla
* @param {number} bytes - Byte cinsinden boyut
* @returns {string} Formatlanmış boyut
*/
const formatFileSize = (bytes) => {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
/**
* E-posta adresi maskele
* @param {string} email - E-posta adresi
* @returns {string} Maskelenmiş e-posta
*/
const maskEmail = (email) => {
const [username, domain] = email.split('@');
const maskedUsername = username.charAt(0) + '*'.repeat(username.length - 2) + username.charAt(username.length - 1);
return `${maskedUsername}@${domain}`;
};
/**
* Telefon numarası maskele
* @param {string} phone - Telefon numarası
* @returns {string} Maskelenmiş telefon
*/
const maskPhone = (phone) => {
if (phone.length < 4) return phone;
return phone.substring(0, 2) + '*'.repeat(phone.length - 4) + phone.substring(phone.length - 2);
};
/**
* Dizi elemanlarını karıştır
* @param {Array} array - Karıştırılacak dizi
* @returns {Array} Karıştırılmış dizi
*/
const shuffleArray = (array) => {
const shuffled = [...array];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
};
/**
* Dizi elemanlarını grupla
* @param {Array} array - Gruplandırılacak dizi
* @param {string} key - Gruplama anahtarı
* @returns {object} Gruplandırılmış obje
*/
const groupBy = (array, key) => {
return array.reduce((groups, item) => {
const group = item[key];
groups[group] = groups[group] || [];
groups[group].push(item);
return groups;
}, {});
};
/**
* Debounce fonksiyonu
* @param {Function} func - Debounce edilecek fonksiyon
* @param {number} wait - Bekleme süresi (ms)
* @returns {Function} Debounce edilmiş fonksiyon
*/
const debounce = (func, wait) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
/**
* Throttle fonksiyonu
* @param {Function} func - Throttle edilecek fonksiyon
* @param {number} limit - Limit süresi (ms)
* @returns {Function} Throttle edilmiş fonksiyon
*/
const throttle = (func, limit) => {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
};
/**
* Renk hex kodunu RGB'ye çevir
* @param {string} hex - Hex renk kodu
* @returns {object} RGB değerleri
*/
const hexToRgb = (hex) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
};
/**
* RGB değerlerini hex koduna çevir
* @param {number} r - Kırmızı değeri
* @param {number} g - Yeşil değeri
* @param {number} b - Mavi değeri
* @returns {string} Hex renk kodu
*/
const rgbToHex = (r, g, b) => {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
};
/**
* URL'den query parametrelerini çıkar
* @param {string} url - URL
* @returns {object} Query parametreleri
*/
const parseQueryParams = (url) => {
const params = {};
const urlObj = new URL(url);
urlObj.searchParams.forEach((value, key) => {
params[key] = value;
});
return params;
};
/**
* Nesne değerlerini temizle (null, undefined, empty string)
* @param {object} obj - Temizlenecek nesne
* @returns {object} Temizlenmiş nesne
*/
const cleanObject = (obj) => {
const cleaned = {};
Object.keys(obj).forEach(key => {
if (obj[key] !== null && obj[key] !== undefined && obj[key] !== '') {
cleaned[key] = obj[key];
}
});
return cleaned;
};
/**
* İki tarih arasındaki farkı hesapla
* @param {Date} date1 - İlk tarih
* @param {Date} date2 - İkinci tarih
* @returns {object} Tarih farkı
*/
const dateDifference = (date1, date2) => {
const diffTime = Math.abs(date2 - date1);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
const diffHours = Math.ceil(diffTime / (1000 * 60 * 60));
const diffMinutes = Math.ceil(diffTime / (1000 * 60));
return {
milliseconds: diffTime,
minutes: diffMinutes,
hours: diffHours,
days: diffDays
};
};
module.exports = {
calculatePagination,
createPaginationMeta,
createResponse,
successResponse,
errorResponse,
generateToken,
verifyToken,
generateRandomString,
safeCompare,
createSlug,
formatDate,
formatPrice,
formatFileSize,
maskEmail,
maskPhone,
shuffleArray,
groupBy,
debounce,
throttle,
hexToRgb,
rgbToHex,
parseQueryParams,
cleanObject,
dateDifference
};