import { identity, drop, take, pipe } from 'ramda' export interface PaginationQuery { offset?: number limit?: number filters?: Record } export interface PaginationResult { items: ItemType[] totalCount: number } export function dropAndTake({ offset = 0, limit = Infinity }) { return pipe(drop(offset), take(limit)) as ( items: Item[] ) => Item[] } export function filterByPropContains(filters: Record) { return function (items: Item[]) { return items.filter((item) => { return Object.entries(filters).every(([fieldName, value]) => item[fieldName].includes(value) ) }) } } export function filterAndCount({ filters, ...dropTakeParams }: PaginationQuery) { return function (items: Item[]) { const filterFunction = filters ? filterByPropContains(filters) : identity const filteredItems = filterFunction(items) return { items: dropAndTake(dropTakeParams)(filteredItems), totalCount: filteredItems.length, } } }