import { isArray, isNil } from 'lodash'; import { ObjectLiteral, SelectQueryBuilder } from 'typeorm'; import { OrderQueryType, PaginateOptions, PaginateReturn } from '@/modules/database/types'; export const paginate = async ( qb: SelectQueryBuilder, options: PaginateOptions, ): Promise> => { const limit = isNil(options.limit) || options.limit < 1 ? 1 : options.limit; const page = isNil(options.page) || options.page < 1 ? 1 : options.page; const start = page >= 1 ? page - 1 : 0; const totalItems = await qb.getCount(); qb.take(limit).skip(start * limit); const items = await qb.getMany(); const totalPages = totalItems % limit === 0 ? Math.floor(totalItems / limit) : Math.floor(totalItems / limit) + 1; const remainder = totalItems % limit === 0 ? limit : totalItems % limit; const itemCount = page < totalPages ? limit : remainder; return { items, meta: { totalItems, itemCount, perPage: limit, totalPages, currentPage: page, }, }; }; export function treePaginate( options: PaginateOptions, data: T[], ): PaginateReturn { const { page, limit } = options; let items: T[] = []; const totalItems = data.length; const totalRst = totalItems / limit; const totalPages = totalRst > Math.floor(totalRst) ? Math.floor(totalRst) + 1 : Math.floor(totalRst); let itemCount = 0; if (page <= totalPages) { itemCount = page === totalPages ? totalItems - (totalPages - 1) * limit : limit; const start = (page - 1) * limit; items = data.slice(start, start + itemCount); } return { meta: { itemCount, totalItems, perPage: limit, totalPages, currentPage: page, }, items, }; } export const getOrderByQuery = ( qb: SelectQueryBuilder, alias: string, orderBy?: OrderQueryType, ) => { if (isNil(orderBy)) { return qb; } if (typeof orderBy === 'string') { return qb.orderBy(`${alias}.${orderBy}`, 'DESC'); } if (isArray(orderBy)) { for (const item of orderBy) { typeof item === 'string' ? qb.addOrderBy(`${alias}.${item}`, 'DESC') : qb.addOrderBy(`${alias}.${item.name}`, item.order); } return qb; } return qb.orderBy(`${alias}.${(orderBy as any).name}`, (orderBy as any).order); };