92 lines
2.7 KiB
JavaScript
92 lines
2.7 KiB
JavaScript
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()
|