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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@libeilong/nestjs

v0.7.1

Published

基于 NestJS 的常用工具集合,主要包含:

Downloads

259

Readme

@libeilong/nestjs

基于 NestJS 的常用工具集合,主要包含:

  • HTTP 日志拦截器
  • 分页 DTO、拦截器与分页参数转换工具
  • 自动继承验证 / 转换 / Swagger 元数据的 DTO 辅助类型(Create / Update / Search)
  • 若干验证相关装饰器与工具

适合在日常后端项目中快速搭建统一的接口风格和 DTO 规范。

安装

pnpm add @libeilong/nestjs
# 或者
npm install @libeilong/nestjs

peerDependencies

本包依赖以下 Nest/验证相关库,请在项目中自行安装合适版本:

  • @nestjs/common
  • @nestjs/swagger
  • @nestjs/mapped-types
  • class-transformer
  • class-validator
  • dayjs
  • colors
  • rxjs
  • express

功能概览

1. HTTP 日志拦截器 HttpLoggerInterceptor

拦截所有 HTTP 请求,输出包含:

  • 状态码
  • 请求方法(带颜色)
  • 路径
  • 耗时(毫秒)

默认使用 Nest 的 Logger('HTTP'),并基于 dayjs 计算耗时,colors 高亮输出。

全局启用示例

// main.ts
import { NestFactory } from '@nestjs/core'
import { AppModule } from './app.module'
import { HttpLoggerInterceptor } from '@libeilong/nestjs'

async function bootstrap() {
  const app = await NestFactory.create(AppModule)

  // 全局拦截器
  app.useGlobalInterceptors(new HttpLoggerInterceptor())

  await app.listen(3000)
}

bootstrap()

2. 分页工具与拦截器

相关导出在 @libeilong/nestjs/pagination 中:

  • PaginationDto:统一的分页入参 DTO
  • PageinationInterceptor:将控制器返回的 [list, count] 结构转换为 { list, count }
  • getPagination(dto):从 PaginationDto 中计算数据库查询用的 limit/offset
  • convertOptions(dto):从 DTO 中拆分出 where 与分页选项

PaginationDto

import { PaginationDto } from '@libeilong/nestjs/pagination'

export class UserListQueryDto extends PaginationDto {
  // 你的其他查询字段
}
  • 字段:
    • page:页码,默认 1;特殊约定:
      • page = -1:表示不分页(getPagination 返回空对象)
      • page = 0:抛出异常,防止非法页码
    • limit:每页数量,默认 10

PageinationInterceptor 使用示例

控制器返回 [list, count],拦截器会自动转换为 { list, count }

// users.controller.ts
import { Controller, Get, Query, UseInterceptors } from '@nestjs/common'
import { PageinationInterceptor, PaginationDto } from '@libeilong/nestjs/pagination'
import { UsersService } from './users.service'

@Controller('users')
@UseInterceptors(PageinationInterceptor)
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  async list(@Query() query: PaginationDto) {
    const { limit, offset } = this.usersService.getPagination(query)
    const [list, count] = await this.usersService.findAndCount({ limit, offset })
    return [list, count]
  }
}

注意:拦截器只对返回值是 [list, count] 形式的数组生效。

getPagination / convertOptions

在 service 中可使用:

// users.service.ts
import { Injectable } from '@nestjs/common'
import { convertOptions } from '@libeilong/nestjs/pagination'
import { UserListQueryDto } from './dto/user-list-query.dto'

@Injectable()
export class UsersService {
  async findList(dto: UserListQueryDto) {
    const { options, where } = convertOptions(dto)
    const { limit, offset } = options

    // 示例:对接 TypeORM / Prisma 等
    const [list, count] = await this.findAndCountFromDb({ where, limit, offset })
    return [list, count] as const
  }
}

3. DTO 辅助类型

位于 @libeilong/nestjs/validator 目录,核心导出:

  • CreateType<T>:生成“创建用” DTO
  • UpdateType<T>:生成“更新用” DTO(所有字段可选)
  • SearchType<T>:生成“搜索用” DTO,自动做查询字符串到正确类型的转换
  • setPaginationDto(dtoClass):自定义 SearchType 使用的分页 DTO(默认 PaginationDto

所有类型都会尽量继承:

  • 原始类上的 class-validator 元数据
  • class-transformer 元数据
  • Swagger 的 @ApiProperty / @ApiPropertyOptional 等元数据

3.1 CreateType<T>

适用于“创建实体”场景:以实体类为基础,复制其字段与验证 / Swagger 配置。

// user.entity.ts
import { IsString, IsEmail } from 'class-validator'
import { ApiProperty } from '@nestjs/swagger'

export class UserEntity {
  @ApiProperty()
  @IsString()
  name: string

  @ApiProperty()
  @IsEmail()
  email: string
}

// dto/create-user.dto.ts
import { CreateType } from '@libeilong/nestjs/validator/create.type'
import { UserEntity } from '../entities/user.entity'

export class CreateUserDto extends CreateType(UserEntity) {}

CreateUserDto 会继承 UserEntity 上的校验规则与 Swagger 文档配置。

3.2 UpdateType<T>

CreateType 基础上,再通过 Swagger 的 PartialType 将所有字段变为可选,适用于“更新”场景:

// dto/update-user.dto.ts
import { UpdateType } from '@libeilong/nestjs/validator/update.type'
import { UserEntity } from '../entities/user.entity'

export class UpdateUserDto extends UpdateType(UserEntity) {}

这样可以保持创建 / 更新 DTO 在字段与文档上的一致性,同时更新时字段全部可选。

3.3 SearchType<T>

用于“列表搜索”的 Query DTO,特点:

  • 自动继承原类的验证与 Swagger 元数据
  • 自动将字符串 Query 参数转换为合适的类型(number / boolean / Date / JSON / string)
  • 默认为所有字段 Partial(可选)
  • 与分页 DTO 进行交叉类型:SearchType(BaseDto) + PaginationDto
// dto/user-search.dto.ts
import { SearchType } from '@libeilong/nestjs/validator/search.type'
import { UserEntity } from '../entities/user.entity'

export class UserSearchDto extends SearchType(UserEntity) {}

在控制器中:

// users.controller.ts
import { Controller, Get, Query, UseInterceptors } from '@nestjs/common'
import { PageinationInterceptor } from '@libeilong/nestjs/pagination'
import { UserSearchDto } from './dto/user-search.dto'
import { UsersService } from './users.service'

@Controller('users')
@UseInterceptors(PageinationInterceptor)
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Get()
  async search(@Query() query: UserSearchDto) {
    const [list, count] = await this.usersService.search(query)
    return [list, count]
  }
}

在 service 中可以配合 convertOptions 使用:

// users.service.ts
import { Injectable } from '@nestjs/common'
import { convertOptions } from '@libeilong/nestjs/pagination'
import { UserSearchDto } from './dto/user-search.dto'

@Injectable()
export class UsersService {
  async search(dto: UserSearchDto) {
    const { options, where } = convertOptions(dto)
    const [list, count] = await this.findAndCountFromDb({ where, ...options })
    return [list, count] as const
  }
}
查询参数自动转换行为

SearchType 内部会:

  1. 根据属性上绑定的 validator / design type 推断字段类型
  2. 对字符串 Query 参数进行转换:
    • 若看起来是 JSON(如 {"a":1}[1,2,3]),尝试 JSON.parse
    • 若目标类型为 Number,尝试转为数字
    • 若为 Boolean,将 'true'/'false' 转为布尔
    • 若为 Date,尝试用 new Date(value) 解析
    • 其他情况保持字符串

这使得复杂查询条件(如 where 对象、数组条件等)可以通过 URL 查询参数以 JSON 形式传入。

3.4 自定义分页 DTO:setPaginationDto

如果需要在 Search DTO 中使用自定义分页类,可以调用:

import { setPaginationDto } from '@libeilong/nestjs/validator/search.type'
import { MyPaginationDto } from './dto/my-pagination.dto'

setPaginationDto(MyPaginationDto)

之后 SearchType 会与 MyPaginationDto 而不是默认 PaginationDto 进行组合。


4. 验证相关装饰器

本包还导出了一些验证辅助:

  • PropertyOptional:统一可选属性的 Swagger / 验证元数据
  • 自定义 IsArray 装饰器:在 query 场景下更友好地处理数组参数

典型用法:

// dto/example.dto.ts
import { PropertyOptional } from '@libeilong/nestjs/validator/property-optional'
import { IsArray } from '@libeilong/nestjs/validator/property/IsArray'

export class ExampleDto {
  @PropertyOptional()
  keyword?: string

  @PropertyOptional()
  @IsArray({ each: true })
  tags?: string[]
}

PropertyOptional 会同步处理:

  • Swagger:将字段标记为可选
  • class-validator:允许字段缺省

IsArray 则封装了对数组类型字段的验证与(在部分场景下)字符串 -> 数组的转换逻辑。


使用建议

  • 在新项目中,可优先使用 CreateType / UpdateType / SearchType 来生成 DTO,尽量减少重复的验证与 Swagger 配置。
  • 建议统一使用 PageinationInterceptorPaginationDto,让列表接口始终返回 { list, count } 的结构。
  • SearchType 支持自动类型转换与 JSON 解析,前端可直接通过查询字符串传递复杂条件,但需要注意:
    • 非法 JSON 会抛出解析错误
    • 类型推断依赖已配置的 validator / design type,必要时请显式声明。

License

MIT