32 lines
1.3 KiB
TypeScript
32 lines
1.3 KiB
TypeScript
/** Offset pagination for a stable dataset; fetch one extra row to detect the next page. */
|
|
export const paginationProperties = {
|
|
limit: { type: "integer", minimum: 1, maximum: 100, default: 25 },
|
|
offset: { type: "integer", minimum: 0, default: 0, description: "Startposition. Für Folgeseiten pagination.nextOffset mit denselben Filtern verwenden." },
|
|
}
|
|
|
|
export function limitFromArgs(args: Record<string, unknown>, fallback = 25) {
|
|
const value = args.limit ?? fallback
|
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1 || value > 100) {
|
|
throw new Error("limit muss eine ganze Zahl zwischen 1 und 100 sein")
|
|
}
|
|
return value
|
|
}
|
|
|
|
export function offsetFromArgs(args: Record<string, unknown>) {
|
|
const value = args.offset ?? 0
|
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
|
|
throw new Error("offset muss eine nicht negative ganze Zahl sein")
|
|
}
|
|
return value
|
|
}
|
|
|
|
export function paginatedResult<T>(rows: T[], args: Record<string, unknown>, fallback = 25) {
|
|
const limit = limitFromArgs(args, fallback)
|
|
const offset = offsetFromArgs(args)
|
|
const hasMore = rows.length > limit
|
|
return {
|
|
rows: rows.slice(0, limit),
|
|
pagination: { limit, offset, hasMore, nextOffset: hasMore ? offset + limit : null },
|
|
}
|
|
}
|