@beignet/core
Version:
Core framework primitives for Beignet
96 lines • 2.83 kB
JavaScript
/**
* 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