export const ok = (data, meta) => ({ data, meta }) export const paginate = (items, query) => { const page = Number(query.page || 1) const perPage = Number(query.perPage || 10) const total = items.length const lastPage = Math.max(1, Math.ceil(total / perPage)) const start = (page - 1) * perPage const sliced = items.slice(start, start + perPage) return { data: sliced, meta: { page, perPage, total, lastPage, currentPage: page }, } } const stringIncludes = (haystack, needle) => String(haystack ?? '') .toLowerCase() .includes(String(needle ?? '').toLowerCase()) export const filterItems = (items, query, rules = {}) => items.filter((item) => { for (const [key, rule] of Object.entries(rules)) { const value = query[key] if (value === '' || value == null) continue if (typeof rule === 'function') { if (!rule(item, value)) return false } else switch (rule) { case 'eq': { if (String(item[key]) !== String(value)) return false break } case 'includes': { if (!stringIncludes(item[key], value)) return false break } case 'fromDate': { if (!item[rule.field || 'createdAt']) continue if (new Date(item[rule.field || 'createdAt']) < new Date(value)) return false break } // No default } } return true }) export const filterDateRange = (items, query, field = 'createdAt') => { if (!query.fromDate && !query.toDate) return items return items.filter((item) => { const v = item[field] if (!v) return !query.fromDate && !query.toDate const d = new Date(v).getTime() if (query.fromDate && d < new Date(query.fromDate).getTime()) return false if (query.toDate && d > new Date(query.toDate).getTime()) return false return true }) } let nextId = 1000 export const makeId = () => ++nextId export const findOrThrow = (list, id) => { const found = list.find((item) => String(item.id) === String(id)) if (!found) { const err = new Error('Not Found') err.response = { status: 404, statusText: 'Not Found', data: { message: 'Not Found' } } throw err } return found } export const removeById = (list, id) => { const idx = list.findIndex((x) => String(x.id) === String(id)) if (idx !== -1) list.splice(idx, 1) } export const updateById = (list, id, patch) => { const idx = list.findIndex((x) => String(x.id) === String(id)) if (idx === -1) return null list[idx] = { ...list[idx], ...patch } return list[idx] } export const isoDaysFromNow = (days) => new Date(Date.now() + days * 86_400_000).toISOString() export const isoNow = () => new Date().toISOString()