npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

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.

npm package License: MIT

📦 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

  1. 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 {}
    }
}
  1. 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
    }
}
  1. 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