hPiBot openclaw ve Opencode ilk versiyonu[B
This commit is contained in:
379
backend/src/utils/helpers.js
Normal file
379
backend/src/utils/helpers.js
Normal file
@@ -0,0 +1,379 @@
|
||||
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
|
||||
};
|
||||
Reference in New Issue
Block a user