Ajout de la pagination sur l'API
This commit is contained in:
86
server/src/common/utils/pagination.utils.ts
Normal file
86
server/src/common/utils/pagination.utils.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { applyDecorators, NotFoundException, Type } from '@nestjs/common'
|
||||
import { QueryPaginationDto } from '../dto/pagination-query.dto'
|
||||
import { ApiExtraModels, ApiOkResponse, ApiResponseNoStatusOptions, getSchemaPath } from '@nestjs/swagger'
|
||||
import { DEFAULT_PAGE_NUMBER, DEFAULT_PAGE_SIZE, PaginateOutputDto } from '../dto/pagination-output.dto'
|
||||
|
||||
export interface PrismaPaginationParams {
|
||||
skip: number
|
||||
take: number
|
||||
}
|
||||
|
||||
export const paginate = (
|
||||
query: QueryPaginationDto,
|
||||
): PrismaPaginationParams => {
|
||||
const size = query.size || DEFAULT_PAGE_SIZE
|
||||
const page = query.page || DEFAULT_PAGE_NUMBER
|
||||
return {
|
||||
skip: size * (page - 1),
|
||||
take: size,
|
||||
}
|
||||
}
|
||||
|
||||
export const paginateOutput = <T>(
|
||||
data: T[],
|
||||
total: number,
|
||||
query: QueryPaginationDto,
|
||||
): PaginateOutputDto<T> => {
|
||||
const page = query.page || DEFAULT_PAGE_NUMBER
|
||||
const size = query.size || DEFAULT_PAGE_SIZE
|
||||
|
||||
const lastPage = Math.ceil(total / size)
|
||||
|
||||
// if data is empty, return empty array
|
||||
if (!data.length) {
|
||||
return {
|
||||
data,
|
||||
meta: {
|
||||
total,
|
||||
lastPage,
|
||||
currentPage: page,
|
||||
totalPerPage: size,
|
||||
prevPage: null,
|
||||
nextPage: null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// if page is greater than last page, throw an error
|
||||
if (page > lastPage) {
|
||||
throw new NotFoundException(
|
||||
`Page ${page} not found. Last page is ${lastPage}`,
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
meta: {
|
||||
total,
|
||||
lastPage,
|
||||
currentPage: page,
|
||||
totalPerPage: size,
|
||||
prevPage: page > 1 ? page - 1 : null,
|
||||
nextPage: page < lastPage ? page + 1 : null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const ApiOkResponsePaginated = <DataDto extends Type<unknown>>(dataDto: DataDto, options?: ApiResponseNoStatusOptions) =>
|
||||
applyDecorators(
|
||||
ApiExtraModels(PaginateOutputDto, dataDto),
|
||||
ApiOkResponse({
|
||||
...options,
|
||||
schema: {
|
||||
allOf: [
|
||||
{ $ref: getSchemaPath(PaginateOutputDto) },
|
||||
{
|
||||
properties: {
|
||||
data: {
|
||||
type: 'array',
|
||||
items: { $ref: getSchemaPath(dataDto) },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
)
|
||||
Reference in New Issue
Block a user