diff --git a/src/__tests__/paginate.repository.spec.ts b/src/__tests__/paginate.repository.spec.ts index a1c93a9..3ef133b 100644 --- a/src/__tests__/paginate.repository.spec.ts +++ b/src/__tests__/paginate.repository.spec.ts @@ -316,6 +316,31 @@ describe('Test paginate function', () => { ); }); + + it('replaces page and limit params if present in route', async () => { + const mockRepository = new MockRepository(10); + + const consoleMock = jest + .spyOn(console, 'warn') + .mockImplementationOnce(() => {}); + + const results = await paginate(mockRepository, { + limit: 4, + page: 2, + route: 'http://example.com/something?page=32&limit=100', + }); + + expect(results.items.length).toBe(4); + expect(results.links?.first).toBe('http://example.com/something?limit=4'); + expect(results.links?.previous).toBe('http://example.com/something?page=1&limit=4'); + expect(results.links?.next).toBe( + 'http://example.com/something?page=3&limit=4', + ); + expect(results.links?.last).toBe( + 'http://example.com/something?page=3&limit=4', + ); + }); + it('Can pass FindConditions', async () => { const mockRepository = new MockRepository(2); diff --git a/src/create-pagination.ts b/src/create-pagination.ts index 4e01eb1..9e8d17e 100644 --- a/src/create-pagination.ts +++ b/src/create-pagination.ts @@ -35,8 +35,6 @@ export function createPaginationObject< route && totalItems !== undefined && currentPage < totalPages; const hasLastPage = route && totalItems !== undefined && totalPages > 0; - const symbol = route && new RegExp(/\?/).test(route) ? '&' : '?'; - const limitLabel = routingLabels && routingLabels.limitLabel ? routingLabels.limitLabel @@ -45,22 +43,21 @@ export function createPaginationObject< const pageLabel = routingLabels && routingLabels.pageLabel ? routingLabels.pageLabel : 'page'; + const isAbsoluteRoute = URL.canParse(route) + const baseUrl = new URL(route, 'https://example.test') + const routes: IPaginationLinks = totalItems !== undefined ? { - first: hasFirstPage ? `${route}${symbol}${limitLabel}=${limit}` : '', + first: hasFirstPage ? buildPageUrl(baseUrl, {page: 0, pageLabel, limitLabel, limit, isRelative: !isAbsoluteRoute }) : '', previous: hasPreviousPage - ? `${route}${symbol}${pageLabel}=${ - currentPage - 1 - }&${limitLabel}=${limit}` + ? buildPageUrl(baseUrl, { page: currentPage - 1, pageLabel, limit, limitLabel, isRelative: !isAbsoluteRoute}) : '', next: hasNextPage - ? `${route}${symbol}${pageLabel}=${ - currentPage + 1 - }&${limitLabel}=${limit}` + ? buildPageUrl(baseUrl, { page: currentPage + 1, pageLabel, limit, limitLabel, isRelative: !isAbsoluteRoute}) : '', last: hasLastPage - ? `${route}${symbol}${pageLabel}=${totalPages}&${limitLabel}=${limit}` + ? buildPageUrl(baseUrl, { page: totalPages, pageLabel, limit, limitLabel, isRelative: !isAbsoluteRoute}) : '', } : undefined; @@ -85,3 +82,14 @@ export function createPaginationObject< // @ts-ignore return new Pagination(items, meta, links); } + +function buildPageUrl(base: URL, params: { pageLabel: string, page: number, limitLabel: string, limit: number, isRelative: boolean}): string { + const workingUrl = new URL(base); + if (params.page < 1) { + workingUrl.searchParams.delete(params.pageLabel) + } else { + workingUrl.searchParams.set(params.pageLabel, params.page.toString()) + } + workingUrl.searchParams.set(params.limitLabel, params.limit.toString()) + return params.isRelative ? `${workingUrl.pathname}${workingUrl.search}${workingUrl.hash}` : workingUrl.toString(); +} \ No newline at end of file