0.1.5Updated 6 months ago
export const PaginationParams = (request: Request) => {
  const query = new URL(request.url).searchParams;

  const page = Math.max(1, parseInt(query.get('page')!)) || 1;
  const page_size = Math.max(1, parseInt(query.get('page_size')!)) || 10;

  return { page, page_size };
}

export const Paginate = <T = any, EF extends Record<string, any> = Record<string, any>>(request: Request, items: T[], total_items: number, extra_fields: EF = {} as EF) => {
  const { page, page_size } = PaginationParams(request);

  let extra_meta = {};
  if(extra_fields.meta) {
    extra_meta = {...extra_fields.meta};
    delete extra_fields.meta;
  }

  return {
    ...extra_fields,
    meta: {
      ...extra_meta,
      page,
      page_size,
      total_pages: Math.max(1, Math.ceil(total_items / page_size)) || 1,
      total_items,
      current_item_count: items.length
    } as I_Pagination,
    items,
  } as PaginationResults<T, EF>
}

export interface I_Pagination {
  page: number
  page_size: number
  total_pages: number
  total_items: number
  current_item_count: number
}

// deno-lint-ignore ban-types
export type PaginationResults<T = any, extra_fields extends Record<string, any> = {}> = extra_fields & {
  meta: I_Pagination,
  items: T[],
}