// /utils/pagination.js const parsePaginationAndSort = (query, defaultSortBy = 'createdAt', defaultSortOrder = 'desc', maxLimit = 100) => { const page = Math.max(1, parseInt(query.page, 10) || 1); let limit = parseInt(query.limit, 10) || 20; if (limit <= 0) limit = 20; if (limit > maxLimit) limit = maxLimit; const skip = (page - 1) * limit; const sortBy = query.sortBy || defaultSortBy; const sortOrder = (query.sortOrder || defaultSortOrder).toLowerCase() === 'asc' ? 1 : -1; const sort = {}; sort[sortBy] = sortOrder; return { page, limit, skip, sort }; }; const buildFilterQuery = (query, searchFields = [], excludedKeys = ['page', 'limit', 'sortBy', 'sortOrder', 'q', 'lang']) => { const filter = {}; // Build field-based exact or boolean filters Object.keys(query).forEach((key) => { if (!excludedKeys.includes(key) && query[key] !== undefined && query[key] !== '') { const val = query[key]; if (val === 'true') { filter[key] = true; } else if (val === 'false') { filter[key] = false; } else if (!isNaN(val) && String(Number(val)) === val) { filter[key] = Number(val); } else { filter[key] = val; } } }); // Build regex search for ?q= across defined text fields if (query.q && searchFields.length > 0) { const searchRegex = new RegExp(query.q, 'i'); filter.$or = searchFields.map((field) => ({ [field]: searchRegex })); } return filter; }; const calculateMeta = (totalCount, page, limit) => { const totalPages = Math.ceil(totalCount / limit) || 0; return { totalCount, totalPages, currentPage: page, limit }; }; module.exports = { parsePaginationAndSort, buildFilterQuery, calculateMeta };