Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 32 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ Pagination helper method for TypeORM repositories or queryBuilders with strict t
```bash
$ yarn add nestjs-typeorm-paginate
```

or

```bash
$ npm i nestjs-typeorm-paginate
```
Expand Down Expand Up @@ -91,7 +93,13 @@ export class CatService {
##### Controller

```ts
import { Controller, DefaultValuePipe, Get, ParseIntPipe, Query } from '@nestjs/common';
import {
Controller,
DefaultValuePipe,
Get,
ParseIntPipe,
Query,
} from '@nestjs/common';
import { CatService } from './cat.service';
import { CatEntity } from './cat.entity';
import { Pagination } from 'nestjs-typeorm-paginate';
Expand Down Expand Up @@ -180,7 +188,6 @@ export class CatsController {
`links.next`: A URL for the next page to call | `""` (blank) if no page to call
`links.last`: A URL for the last page to call | `""` (blank) if no `route` is defined


> Do note that `links.first` may not have the 'page' query param defined

## Find Parameters
Expand Down Expand Up @@ -210,7 +217,7 @@ import { Entity, OneToMany } from 'typeorm';

@Entity()
export class CatEntity {
@OneToMany(t => TigerKingEntity, tigerKing.cats, {
@OneToMany((t) => TigerKingEntity, tigerKing.cats, {
eager: true,
})
tigerKings: TigerKingEntity[];
Expand Down Expand Up @@ -268,12 +275,11 @@ Let's assume there's a joined table that matches each cat with its cat toys.
And we want to bring how many toys each cat has.

```typescript

const queryBuilder = this.repository
.createQueryBuilder<{ type: string; totalLives: string }>('cat')
.leftJoinAndSelect('cat.toys', 'toys')
.addSelect('COUNT(toys)::INTEGER', 'toyCount')
.groupBy('cat.name');
.leftJoinAndSelect('cat.toys', 'toys')
.addSelect('COUNT(toys)::INTEGER', 'toyCount')
.groupBy('cat.name');
```

This will allow us to get the paginated cats information with the additional raw query to build our actual response value.
Expand Down Expand Up @@ -329,41 +335,48 @@ The rawResults array will look something like this:
If you wanted to alter the meta data that is returned from the pagination object. Then use the `metaTransformer` in the options like so

```ts

class CustomPaginationMeta {
constructor(
public readonly count: number,
public readonly total: number,
) {}
}

return paginate<MyEntity, CustomPaginationMeta>(this.repository, {
return paginate<MyEntity, CustomPaginationMeta>(this.repository, {
page,
limit,
metaTransformer: (meta: IPaginationMeta): CustomPaginationMeta => new CustomPaginationMeta(
meta.itemCount,
meta.totalItems,
),
});
metaTransformer: (meta: IPaginationMeta): CustomPaginationMeta =>
new CustomPaginationMeta(meta.itemCount, meta.totalItems),
});
```

This will result in the above returning `CustomPaginationMeta` in the `meta` property instead of the default `IPaginationMeta`.


## Custom links query params labels

If you want to alter the `limit` and/or `page` labels in meta links, then use `routingLabels` in the options like so

```ts

return paginate<MyEntity>(this.repository, {
return paginate<MyEntity>(this.repository, {
page,
limit,
routingLabels: {
limitLabel: 'page-size', // default: limit
pageLabel: 'current-page', //default: page
}
});
},
});
```

This will result links like `http://example.com/something?current-page=1&page-size=3`.

## Custom re-routing latest page have items

If you just want to return latest has items when the parameter `page` was over than `page` calculated in the database at the moment, then use `routingLatest` as the options. Make sure you not set countQueries to `false`. It will be ignored when pagination is disabled and `routingLatest` option won't be affect anymore.

```ts
return paginate<MyEntity>(this.repository, {
page,
limit,
routingLatest: true,
});
```
13 changes: 13 additions & 0 deletions src/__tests__/paginate-raw-and-entities.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,17 @@ describe('Test paginateRawAndEntities function', () => {
expect(result.meta.totalItems).toBe(undefined);
expect(result.meta.totalPages).toBe(undefined);
});

it('Can routing to latest page have items', async () => {
const [result] = await paginateRawAndEntities(queryBuilder, {
limit: 10,
page: 2,
countQueries: true,
routingLatest: true,
});

expect(result).toBeInstanceOf(Pagination);
expect(result.meta.totalItems).toEqual(10);
expect(result.meta.currentPage).toEqual(1);
});
});
15 changes: 14 additions & 1 deletion src/__tests__/paginate-raw.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('Test paginateRaw function', () => {
});

afterAll(async () => {
await queryBuilder.delete();
queryBuilder.delete();
await app.close();
});

Expand Down Expand Up @@ -180,4 +180,17 @@ describe('Test paginateRaw function', () => {
expect(result.meta.totalItems).toBe(undefined);
expect(result.meta.totalPages).toBe(undefined);
});

it('Can routing to latest page have items', async () => {
const result = await paginateRaw(queryBuilder, {
limit: 10,
page: 2,
countQueries: true,
routingLatest: true,
});

expect(result).toBeInstanceOf(Pagination);
expect(result.meta.totalItems).toEqual(10);
expect(result.meta.currentPage).toEqual(1);
});
});
26 changes: 26 additions & 0 deletions src/__tests__/paginate.query.builder.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,30 @@ describe('Paginate with queryBuilder', () => {
expect(result).toBeInstanceOf(Pagination);
expect(result.meta.totalItems).toEqual(10);
});

it('Can routing to latest page have items', async () => {
await testRelatedQueryBuilder
.createQueryBuilder()
.insert()
.into(TestRelatedEntity)
.values([
{ id: 1, testId: 1 },
{ id: 2, testId: 1 },
{ id: 3, testId: 1 },
])
.execute();

const qb = queryBuilder.leftJoinAndSelect('t.related', 'r');

const result = await paginate(qb, {
limit: 15,
page: 2,
routingLatest: true,
countQueries: true,
});

expect(result).toBeInstanceOf(Pagination);
expect(result.meta.totalItems).toEqual(10);
expect(result.meta.currentPage).toEqual(1);
});
});
6 changes: 6 additions & 0 deletions src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ export interface IPaginationOptions<CustomMetaType = IPaginationMeta> {
* Enables or disables query result caching.
*/
cacheQueries?: TypeORMCacheType;

/**
* @default false
* Enables or disables routing to the latest page have items
*/
routingLatest?: boolean;
}

export type TypeORMCacheType =
Expand Down
Loading