Yuzhe's Blog

yuzhes

@faster-crud v0.2.0:从 4 个包到 18 个——构建完整的框架生态

@faster-crud v0.2.0:从 4 个包到 18 个

GitHub: bkmashiro/nest-faster-crud
npm: @faster-crud

v0.1.x 时,@faster-crud 只覆盖一个场景:NestJS + TypeORM 的类型安全 CRUD,配上 Vue 3 前端绑定。实用,但范围很窄。

v0.2.0 完全不同了。


v0.2.0 新增内容

7 个 ORM / 数据库适配器

包名数据库
@faster-crud/typeormTypeORM(MySQL、Postgres、SQLite…)
@faster-crud/prismaPrisma
@faster-crud/drizzleDrizzle ORM
@faster-crud/mongooseMongoDB(Mongoose)
@faster-crud/mikro-ormMikroORM
@faster-crud/expressExpress 框架适配器
@faster-crud/fastifyFastify 框架适配器

每个适配器都暴露相同的 ResourceService 接口——换 ORM 不需要改 Controller。

3 个前端框架

// Vue 3(已有)
const { data, total, create } = useCrud<User>('/api/users')

// React(新增)
const { data, total, create } = useCrud<User>('/api/users')

// Svelte 5(新增,runes 风格)
const store = createCrudStore<User>('/api/users')

// SolidJS(新增)
const store = createCrudStore<User>('/api/users')

四个框架共享同一套 ResourceMeta 协议——一份 Schema 驱动所有 UI。

API 层适配器

// Hono(已有)
app.route('/users', createCrudRouter(User, userService))

// tRPC(新增)
const appRouter = createCrudRouter(User, userService)
// 自动生成 list / get / create / update / remove procedure

// GraphQL(新增)
@Module({ providers: [CrudResolver(User, UserService)] })
// 自动生成 @ObjectType、@InputType、@Query、@Mutation

开发工具

@faster-crud/gen — CLI 代码生成器:

npx @faster-crud/gen add User --fields "name:string,email:string,age:number"
# 生成:entity、service、module、controller、tests

@faster-crud/validation — 不依赖 class-validator 的独立验证:

const errors = validateEntity(dto, User)
// 内置:required、email、length、range、pattern

@faster-crud/auth — JWT 鉴权集成:

@Controller('users')
@Protected()
class UsersController extends CrudControllerFactory(User, UserService) {
  @AdminOnly()
  remove(@Param('id') id: number) { ... }
}

核心设计:为什么所有东西共享一个 Schema

@faster-crud 的核心思路:一个带装饰器的 Entity 类,包含了生成完整 CRUD 栈所需的一切信息。

@Resource('users')
class User {
  @Col() id!: number

  @Searchable()
  @Rule.required()
  @Col({ ui: { widget: 'text', label: '用户名' } })
  name!: string

  @Hidden('list')   // 在列表中隐藏,详情中可见
  @Col()
  email!: string

  @Ignore()         // 完全排除在 CRUD 之外
  passwordHash!: string
}

从这一个定义出发,@faster-crud 能自动推导出:

运行时的 ResourceMeta 端点(GET /__crud/meta)将这些信息序列化,前端无需代码生成即可动态自省 Schema。


过滤运算符系统

一套统一的过滤查询语言,映射到各 ORM 的原生查询构建器:

// HTTP 查询
GET /users?filters[name][op]=like&filters[name][value]=john
GET /users?filters[age][op]=between&filters[age][value][]=18&filters[age][value][]=30
运算符TypeORMPrismaDrizzleMongoose
likeLike('%val%'){ contains: val }like(col, '%val%'){ $regex: val }
betweenBetween(a, b){ gte: a, lte: b }between(col, a, b){ $gte: a, $lte: b }
neNot(val){ not: val }ne(col, val){ $ne: val }

测试策略:300+ 测试

每个包都带单元测试,模拟底层 ORM/框架的行为:

// Prisma 适配器测试示例
const prismaModel = {
  create: jest.fn(async ({ data }) => ({ id: 1, ...data })),
  findMany: jest.fn(async () => []),
  count: jest.fn(async () => 0),
}

const UserService = PrismaResourceService(User, prismaModel)
await service.list({ filters: { name: { op: 'like', value: 'John' } } })

expect(prismaModel.findMany).toHaveBeenCalledWith({
  where: { name: { contains: 'John' } },
  skip: 0, take: 10,
})

18 个包,300+ 测试,CI 全绿。


后续计划


完整包列表在 npmjs.com,源码在 bkmashiro/nest-faster-crud