379 lines
8.9 KiB
JavaScript
379 lines
8.9 KiB
JavaScript
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
|
||
}; |