nestjs-soft-pagination-filter-sort
v1.0.0
Published
Base of soft pagination, filtrable and sortable package as adapter for nestjs
Downloads
6
Readme
Created for solving advanced paginating, advanced filtering and advanced sorting with contributing Front-end developers in the Nestjs Back-end framework.
📦 Install
npm i nestjs-soft-pagination-filter-sort
✍️ Note: With this package you can adapting all communications between ORMs, APIs, data storage and etc with your application by one code style using filters.
🚀 Usage
0- 💉 Importing module
import { SoftPaginationFilterSortModule } from 'nestjs-soft-pagination-filter-sort'
@Module({
imports: [
SoftPaginationFilterSortModule,
],
})
1- 📃 Pagination
1-1- Simple implementation
You must use the pagination interceptor
- Request
{
"page": 1,
"size": 2,
"offset": 0,
"sort": { "id": "asc" },
"filter": {}
}
- Response
{
"total": 10,
"page": 1,
"size": 2,
"hasPrevPage": false,
"hasNextPage": true,
"list": [
{ "id": 1, "name": "Tomas", "color": "gray" },
{ "id": 2, "name": "Anna", "color": "white" }
]
}
- Controller
import {
BasePaginatedResponseInterceptor,
PaginatedModel,
PaginatedRequestDTOInterface,
} from 'nestjs-soft-pagination-filter-sort'
@Controller('cat')
export class CatController
{
@UseInterceptors(BasePaginatedResponseInterceptor<YourModel, PaginatedModel<YourModel>>)
@Get()
getAll(@Query() paginatedRequestDTO: PaginatedRequestDTOInterface)
{
return {
total: 10,
list: [
{ id: 1, name: 'Tomas', color: 'gray' },
{ id: 2, name: 'Anna', color: 'white' },
],
}
}
}
1-2- Advanced implementation
✍️ Note: You can add change of DTOs of request or response of pagination system.
- Request DTO
import { PaginatedRequestDTOInterface } from 'nestjs-soft-pagination-filter-sort'
export class PaginatedRequestDTO implements PaginatedRequestDTOInterface
{
page?: number
size?: number
offset?: number
sort?: Record<string, SortTypesEnum>
filter?: TFilter
}
- Response DTO
import { PaginatedResponseDTOInterface } from 'nestjs-soft-pagination-filter-sort'
export class PaginatedResponseDTO<TData> implements PaginatedResponseDTOInterface<TData>
{
status: 'success' | 'warning' | 'error'
total: number
page?: number
size?: number
hasPrevPage: boolean
hasNextPage: boolean
list: TData[]
}
- Custom pagination interceptor
✍️ Note: You must import custom interceptor as global for usage in all modules without any imports in another modules.
import { BasePaginatedResponseInterceptor } from 'nestjs-soft-pagination-filter-sort'
export class PaginatedResponseInterceptor<TData, TModel extends PaginatedModel<TData>>
extends BasePaginatedResponseInterceptor<TData, TModel>
{
intercept(context: ExecutionContext, next: CallHandler): Observable<PaginatedResponseDTO<TData>>
{
// If you changes request or response DTOs, You can handles those here or
// customize of all them.
const query = context.switchToHttp().getRequest().query as PaginatedResponseDTO
if (typeof query.page === 'string') query.page = Number.parseInt(`${ query.page }`)
if (typeof query.size === 'string') query.size = Number.parseInt(`${ query.size }`)
if (typeof query.offset === 'string') query.offset = Number.parseInt(`${ query.offset }`)
return next.handle().pipe(map((value: TModel) => super.buildResponse<
{ status: 'success' | 'warning' | 'errpr' }
>(value, query, { status: 'success' })))
}
}
Example
- Request
{
"page": 1,
"size": 2,
"offset": 0,
"sort": { "id": "asc" },
"filter": {}
}
- Response (In the response, status key added by interceptor automatically)
{
"status": "success",
"total": 10,
"page": 1,
"size": 2,
"hasPrevPage": false,
"hasNextPage": true,
"list": [
{ "id": 1, "name": "Tomas", "color": "gray" },
{ "id": 2, "name": "Anna", "color": "white" }
]
}
2- 🔎 Filter with Sort
You can create main filter class for each ORMs, API repositories or any data storages and filter all of them with own structure! 😎❤️
Sequelize example
- Create filter class for sequelize
✍️ Note: You can set the below class as abstract or not by your decision. If you want create a base structure for your filtering, you can set it as a class or, set the it as a abstract class and create custom filters for all data getters such as repositories.
import { FindOptions } from 'sequelize'
import { Filter } from 'nestjs-soft-pagination-filter-sort'
export class SequelizeFilter<T> extends Filter<T>
{
getQuery(data: T): FindOptions<T>
{
return {}
}
}
- Create custom filter for get cats
export class CatsGetAllDatabaseSequelizeFilter extends SequelizeFilter<{ color: string }>
{
getQuery(data?: { color: string }, name?: string):
FindOptions<{ color: string }>
{
const filter: FindOptions<T> = {}
// Your operations below and
// the end, return filter
return filter
}
}
- New cats controller after changes
import {
DatabaseFilterService,
PaginatedModel,
} from 'nestjs-soft-pagination-filter-sort'
@Controller('cats')
export class CatsController
{
constructor(
@InjectModel(Cat) private catModel: typeof Cat,
private readonly databaseFilterService: DatabaseFilterService<CatsGetAllDatabaseSequelizeFilter>,
) {}
@UseInterceptors(PaginatedResponseInterceptor<YourModel, PaginatedModel<YourModel>>)
@Get()
getAll(@Query() paginatedRequestDTO: PaginatedRequestDTO)
{
const databaseToolFilter = new CatsGetAllDatabaseSequelizeFilter()
const queryFilter = this.databaseFilterService.getQuery(databaseToolFilter, data.filter, 'Miu-Miu')
return {
total: await this.catModel.count({ where: queryFilter }),
list: await this.catModel.findAll({ where: queryFilter }),
offset: (paginatedRequestDTO.page && paginatedRequestDTO.size)
&& paginatedRequestDTO.page * paginatedRequestDTO.size + (paginatedRequestDTO.offset || 0),
limit: paginatedRequestDTO.size,
order: paginatedRequestDTO.sort && Object.entries(paginatedRequestDTO.sort),
}
}
}
Contributing
Before creating an issue, please ensure that it hasn't already been reported/suggested, and double-check the examples.
See the contribution guide if you'd like to submit a PR.
Help
If you don't understand something in the examples, you are experiencing problems, or you just need a gentle nudge in the right direction, please don't hesitate to contact us.
License
The MIT License (MIT)
Copyright © 2023