91 lines
1.9 KiB
TypeScript
91 lines
1.9 KiB
TypeScript
/**
|
|
* Pagination utilities for API endpoints
|
|
*/
|
|
|
|
export interface PaginationParams {
|
|
page?: number;
|
|
limit?: number;
|
|
sortBy?: string;
|
|
sortOrder?: "asc" | "desc";
|
|
}
|
|
|
|
export interface PaginationMetadata {
|
|
page: number;
|
|
limit: number;
|
|
total: number;
|
|
totalPages: number;
|
|
hasNextPage: boolean;
|
|
hasPrevPage: boolean;
|
|
}
|
|
|
|
export interface PaginatedResponse<T> {
|
|
data: T[];
|
|
pagination: PaginationMetadata;
|
|
}
|
|
|
|
/**
|
|
* Parse pagination parameters from URL search params
|
|
*/
|
|
export function parsePaginationParams(searchParams: URLSearchParams): {
|
|
page: number;
|
|
limit: number;
|
|
sortBy?: string;
|
|
sortOrder: "asc" | "desc";
|
|
} {
|
|
const page = Math.max(1, parseInt(searchParams.get("page") || "1", 10));
|
|
const limit = Math.min(
|
|
100,
|
|
Math.max(1, parseInt(searchParams.get("limit") || "20", 10)),
|
|
);
|
|
const sortBy = searchParams.get("sortBy") || undefined;
|
|
const sortOrder = (searchParams.get("sortOrder") || "desc") as "asc" | "desc";
|
|
|
|
return { page, limit, sortBy, sortOrder };
|
|
}
|
|
|
|
/**
|
|
* Create pagination metadata
|
|
*/
|
|
export function createPaginationMetadata(
|
|
page: number,
|
|
limit: number,
|
|
total: number,
|
|
): PaginationMetadata {
|
|
const totalPages = Math.ceil(total / limit);
|
|
|
|
return {
|
|
page,
|
|
limit,
|
|
total,
|
|
totalPages,
|
|
hasNextPage: page < totalPages,
|
|
hasPrevPage: page > 1,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Apply pagination to an array (for in-memory pagination)
|
|
* Use this sparingly - prefer database-level pagination
|
|
*/
|
|
export function paginateArray<T>(
|
|
items: T[],
|
|
page: number,
|
|
limit: number,
|
|
): PaginatedResponse<T> {
|
|
const offset = (page - 1) * limit;
|
|
const paginatedItems = items.slice(offset, offset + limit);
|
|
|
|
return {
|
|
data: paginatedItems,
|
|
pagination: createPaginationMetadata(page, limit, items.length),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Calculate SQL LIMIT and OFFSET from page and limit
|
|
*/
|
|
export function getPaginationOffsets(page: number, limit: number) {
|
|
const offset = (page - 1) * limit;
|
|
return { limit, offset };
|
|
}
|