UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

96 lines 2.83 kB
/** * Error thrown when pagination input is invalid. */ export class PaginationError extends Error { constructor(message) { super(message); this.name = "PaginationError"; } } function assertPositiveInteger(name, value) { if (!Number.isInteger(value) || value < 1) { throw new PaginationError(`${name} must be a positive integer.`); } } function normalizeLimit(input, options) { assertPositiveInteger("defaultLimit", options.defaultLimit); assertPositiveInteger("maxLimit", options.maxLimit); if (options.defaultLimit > options.maxLimit) { throw new PaginationError("defaultLimit must be less than or equal to maxLimit."); } if (input == null) return options.defaultLimit; if (!Number.isInteger(input) || input < 1) { throw new PaginationError("limit must be a positive integer."); } return Math.min(input, options.maxLimit); } /** * Normalize offset pagination input. * * The limit is defaulted and clamped to `maxLimit`; offset must be a * non-negative integer. */ export function normalizeOffsetPage(input, options) { const limit = normalizeLimit(input.limit, options); const offset = input.offset ?? 0; if (!Number.isInteger(offset) || offset < 0) { throw new PaginationError("offset must be a non-negative integer."); } return { kind: "offset", limit, offset, }; } /** * Normalize cursor pagination input. * * The limit is defaulted and clamped to `maxLimit`; cursor must be a string or * null. */ export function normalizeCursorPage(input, options) { const limit = normalizeLimit(input.limit, options); const cursor = input.cursor ?? null; if (cursor !== null && typeof cursor !== "string") { throw new PaginationError("cursor must be a string or null."); } return { kind: "cursor", limit, cursor, }; } /** * Create an offset page result and derive `hasMore`. */ export function offsetPageResult(items, page, total) { if (!Number.isInteger(total) || total < 0) { throw new PaginationError("total must be a non-negative integer."); } return { items: [...items], page: { ...page, total, hasMore: page.offset + items.length < total, }, }; } /** * Create a cursor page result and derive `hasMore` from `nextCursor`. */ export function cursorPageResult(items, page, nextCursor) { if (nextCursor !== null && typeof nextCursor !== "string") { throw new PaginationError("nextCursor must be a string or null."); } return { items: [...items], page: { ...page, nextCursor, hasMore: nextCursor !== null, }, }; } //# sourceMappingURL=index.js.map