UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.

127 lines (126 loc) 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Paginator = void 0; class Paginator { #totalItems; #perPage; #currentPage; constructor(options) { const { totalItems, itemsPerPage = 10, currentPage = 1 } = options ?? {}; this.#totalItems = Math.max(0, Number(totalItems)); this.#perPage = Math.max(1, Number(itemsPerPage)); this.#currentPage = Math.max(1, Number(currentPage)); } withPage(page) { const safePage = Math.min(Math.max(1, page), this.totalPages()); return new Paginator({ totalItems: this.#totalItems, itemsPerPage: this.#perPage, currentPage: safePage, }); } withPerPage(perPage) { const safePerPage = Math.max(1, perPage); return new Paginator({ totalItems: this.#totalItems, itemsPerPage: safePerPage, currentPage: this.#currentPage, }); } withTotalItems(totalItems) { const safeTotalItems = Math.max(0, totalItems); return new Paginator({ totalItems: safeTotalItems, itemsPerPage: this.#perPage, currentPage: this.#currentPage, }); } withOptions(options) { const newTotalItems = Math.max(0, options.totalItems ? Number(options.totalItems) : this.#totalItems); const newItemsPerPage = Math.max(1, options.itemsPerPage ? Number(options.itemsPerPage) : this.#perPage); const totalPages = Math.ceil(newTotalItems / newItemsPerPage); const newCurrentPage = Math.min(Math.max(1, options.currentPage ? Number(options.currentPage) : this.#currentPage), totalPages); return new Paginator({ totalItems: newTotalItems, itemsPerPage: newItemsPerPage, currentPage: newCurrentPage, }); } offset() { return (this.#currentPage - 1) * this.#perPage; } getOffset() { return this.offset(); } skipCount() { return this.offset(); } totalPages() { return Math.ceil(this.#totalItems / this.#perPage); } getMeta() { const totalPages = this.totalPages(); return { totalItems: this.#totalItems, currentPage: this.#currentPage, itemsPerPage: this.#perPage, totalPages, hasPrev: this.hasPrevPage(), hasNext: this.hasNextPage(), isFirst: this.isFirstPage(), isLast: this.isLastPage(), offset: this.offset(), }; } nextPage() { return this.#currentPage < this.totalPages() ? this.#currentPage + 1 : null; } prevPage() { return this.#currentPage > 1 ? this.#currentPage - 1 : null; } isFirstPage() { return this.#currentPage === 1; } isLastPage() { return this.#currentPage === this.totalPages(); } hasPrevPage() { return this.#currentPage > 1; } hasNextPage() { return this.#currentPage < this.totalPages(); } pageList(options = {}) { const total = this.totalPages(); const edgeCount = Math.max(0, options.edgeCount ?? 1); const siblingCount = Math.max(0, options.siblingCount ?? 1); const start = Math.max(this.#currentPage - siblingCount, edgeCount + 1); const end = Math.min(this.#currentPage + siblingCount, total - edgeCount); const _getRange = (from, to) => { return from > to ? [] : Array.from({ length: to - from + 1 }, (_, i) => from + i); }; const startPages = _getRange(1, edgeCount); const middlePages = _getRange(start, end); const endPages = _getRange(total - edgeCount + 1, total); const pages = new Set([...startPages, ...middlePages, ...endPages]); return Array.from(pages).sort((a, b) => a - b); } firstPage() { return 1; } lastPage() { return this.totalPages(); } isPageValid(page) { const p = Math.floor(page); return p >= 1 && p <= this.totalPages(); } static fromMeta(meta) { return new Paginator({ totalItems: meta.totalItems, itemsPerPage: meta.itemsPerPage, currentPage: meta.currentPage, }); } } exports.Paginator = Paginator;