| 12 | * @see https://datatracker.ietf.org/doc/html/rfc5988 |
| 13 | */ |
| 14 | export const buildLinkHeader = (request: NextRequest, params: PaginationParams): string | null => { |
| 15 | const { page, perPage, totalCount, extraParams } = params; |
| 16 | const totalPages = Math.ceil(totalCount / perPage); |
| 17 | |
| 18 | if (totalPages <= 1) return null; |
| 19 | |
| 20 | const buildUrl = (targetPage: number): string => { |
| 21 | const url = new URL(request.url); |
| 22 | url.search = ''; |
| 23 | url.searchParams.set('page', targetPage.toString()); |
| 24 | url.searchParams.set('perPage', perPage.toString()); |
| 25 | if (extraParams) { |
| 26 | for (const [key, value] of Object.entries(extraParams)) { |
| 27 | url.searchParams.set(key, value); |
| 28 | } |
| 29 | } |
| 30 | return url.toString(); |
| 31 | }; |
| 32 | |
| 33 | const links: string[] = []; |
| 34 | links.push(`<${buildUrl(1)}>; rel="first"`); |
| 35 | if (page > 1) links.push(`<${buildUrl(page - 1)}>; rel="prev"`); |
| 36 | if (page < totalPages) links.push(`<${buildUrl(page + 1)}>; rel="next"`); |
| 37 | links.push(`<${buildUrl(totalPages)}>; rel="last"`); |
| 38 | |
| 39 | return links.join(', '); |
| 40 | }; |