UNPKG

arvox-backend

Version:

Un framework backend moderne et modulaire basé sur Hono, TypeScript et l'architecture hexagonale avec authentification Better Auth + Drizzle intégrée

129 lines 4.19 kB
/** * Utility class for handling pagination logic */ export class PaginationUtil { defaultPage = 1; defaultLimit = 10; maxLimit = 100; /** * Extract pagination parameters from Hono context * @param c - Hono context * @returns Pagination parameters with skip calculated */ extractFromContext(c) { const page = Math.max(1, parseInt(c.req.query('page') || '1', 10)); const limit = Math.min(this.maxLimit, Math.max(1, parseInt(c.req.query('limit') || String(this.defaultLimit), 10))); const skip = (page - 1) * limit; return { page, limit, skip }; } /** * Calculate pagination metadata * @param total - Total number of items * @param page - Current page * @param limit - Items per page * @returns Pagination metadata */ calculateMetadata(total, page, limit) { const totalPages = Math.ceil(total / limit); const hasNext = page < totalPages; const hasPrev = page > 1; const startIndex = (page - 1) * limit + 1; const endIndex = Math.min(page * limit, total); return { total, page, limit, totalPages, hasNext, hasPrev, startIndex, endIndex, showing: `${startIndex}-${endIndex} of ${total}` }; } /** * Validate pagination parameters * @param page - Page number * @param limit - Items per page * @throws Error if parameters are invalid */ validate(page, limit) { if (page < 1) { throw new Error('Page number must be greater than 0'); } if (limit < 1) { throw new Error('Limit must be greater than 0'); } if (limit > this.maxLimit) { throw new Error(`Limit cannot exceed ${this.maxLimit}`); } } /** * Create pagination links for navigation * @param baseUrl - Base URL for the resource * @param page - Current page * @param totalPages - Total number of pages * @param limit - Items per page * @returns Navigation links */ createLinks(baseUrl, page, totalPages, limit) { const links = { first: `${baseUrl}?page=1&limit=${limit}`, last: `${baseUrl}?page=${totalPages}&limit=${limit}`, prev: page > 1 ? `${baseUrl}?page=${page - 1}&limit=${limit}` : null, next: page < totalPages ? `${baseUrl}?page=${page + 1}&limit=${limit}` : null, self: `${baseUrl}?page=${page}&limit=${limit}` }; // Remove null values return Object.fromEntries(Object.entries(links).filter(([_, value]) => value !== null)); } /** * Apply pagination to an array (for in-memory pagination) * @param items - Array of items * @param page - Page number * @param limit - Items per page * @returns Paginated subset of items */ applyToArray(items, page, limit) { const skip = (page - 1) * limit; return items.slice(skip, skip + limit); } /** * Create a paginated response structure * @param items - Array of items * @param total - Total count * @param page - Current page * @param limit - Items per page * @param baseUrl - Optional base URL for links * @returns Complete paginated response */ createResponse(items, total, page, limit, baseUrl) { const metadata = this.calculateMetadata(total, page, limit); const links = baseUrl ? this.createLinks(baseUrl, page, metadata.totalPages, limit) : undefined; return { items, pagination: { ...metadata, ...(links && { links }) } }; } /** * Get default pagination values * @returns Default page and limit values */ getDefaults() { return { page: this.defaultPage, limit: this.defaultLimit }; } /** * Get maximum allowed limit * @returns Maximum limit value */ getMaxLimit() { return this.maxLimit; } } //# sourceMappingURL=pagination.util.js.map