87 lines
2.1 KiB
TypeScript
87 lines
2.1 KiB
TypeScript
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) },
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
}),
|
|
)
|