create-hest-app 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +211 -0
  2. package/dist/index.js +127 -0
  3. package/package.json +50 -0
  4. package/templates/base/.prettierrc +33 -0
  5. package/templates/base/.vscode/extensions.json +79 -0
  6. package/templates/base/.vscode/settings.json +70 -0
  7. package/templates/base/README.md +562 -0
  8. package/templates/base/eslint.config.ts +26 -0
  9. package/templates/base/package.json +62 -0
  10. package/templates/base/src/app.controller.ts +39 -0
  11. package/templates/base/src/app.module.ts +12 -0
  12. package/templates/base/src/app.service.ts +30 -0
  13. package/templates/base/src/common/filters/http-exception.filter.ts +34 -0
  14. package/templates/base/src/common/interceptors/response.interceptor.ts +38 -0
  15. package/templates/base/src/index.ts +35 -0
  16. package/templates/base/src/modules/custom-validation/custom-validation.controller.ts +146 -0
  17. package/templates/base/src/modules/custom-validation/custom-validation.module.ts +10 -0
  18. package/templates/base/src/modules/custom-validation/custom-validation.service.ts +33 -0
  19. package/templates/base/src/modules/custom-validation/dto/custom-validation.dto.ts +132 -0
  20. package/templates/base/src/modules/users/dto/user.dto.ts +64 -0
  21. package/templates/base/src/modules/users/entities/user.entity.ts +9 -0
  22. package/templates/base/src/modules/users/users.controller.ts +68 -0
  23. package/templates/base/src/modules/users/users.module.ts +10 -0
  24. package/templates/base/src/modules/users/users.service.ts +55 -0
  25. package/templates/base/tsconfig.json +19 -0
  26. package/templates/base_scalar/.prettierrc +32 -0
  27. package/templates/base_scalar/.vscode/extensions.json +79 -0
  28. package/templates/base_scalar/.vscode/settings.json +70 -0
  29. package/templates/base_scalar/README.md +562 -0
  30. package/templates/base_scalar/eslint.config.ts +26 -0
  31. package/templates/base_scalar/package.json +63 -0
  32. package/templates/base_scalar/src/app.controller.ts +196 -0
  33. package/templates/base_scalar/src/app.module.ts +12 -0
  34. package/templates/base_scalar/src/app.service.ts +30 -0
  35. package/templates/base_scalar/src/common/filters/http-exception.filter.ts +34 -0
  36. package/templates/base_scalar/src/common/interceptors/response.interceptor.ts +38 -0
  37. package/templates/base_scalar/src/index.ts +67 -0
  38. package/templates/base_scalar/src/modules/custom-validation/custom-validation.controller.ts +146 -0
  39. package/templates/base_scalar/src/modules/custom-validation/custom-validation.module.ts +10 -0
  40. package/templates/base_scalar/src/modules/custom-validation/custom-validation.service.ts +33 -0
  41. package/templates/base_scalar/src/modules/custom-validation/dto/custom-validation.dto.ts +132 -0
  42. package/templates/base_scalar/src/modules/users/dto/user.dto.ts +64 -0
  43. package/templates/base_scalar/src/modules/users/entities/user.entity.ts +9 -0
  44. package/templates/base_scalar/src/modules/users/users.controller.ts +68 -0
  45. package/templates/base_scalar/src/modules/users/users.module.ts +10 -0
  46. package/templates/base_scalar/src/modules/users/users.service.ts +55 -0
  47. package/templates/base_scalar/tsconfig.json +19 -0
  48. package/templates/cqrs/.prettierrc +33 -0
  49. package/templates/cqrs/.vscode/extensions.json +79 -0
  50. package/templates/cqrs/.vscode/settings.json +70 -0
  51. package/templates/cqrs/README.md +234 -0
  52. package/templates/cqrs/eslint.config.ts +26 -0
  53. package/templates/cqrs/package.json +62 -0
  54. package/templates/cqrs/src/app.controller.ts +28 -0
  55. package/templates/cqrs/src/app.module.ts +12 -0
  56. package/templates/cqrs/src/app.service.ts +8 -0
  57. package/templates/cqrs/src/common/filters/http-exception.filter.ts +34 -0
  58. package/templates/cqrs/src/common/interceptors/response.interceptor.ts +38 -0
  59. package/templates/cqrs/src/index.ts +38 -0
  60. package/templates/cqrs/src/modules/custom-validation/custom-validation.controller.ts +146 -0
  61. package/templates/cqrs/src/modules/custom-validation/custom-validation.module.ts +10 -0
  62. package/templates/cqrs/src/modules/custom-validation/custom-validation.service.ts +33 -0
  63. package/templates/cqrs/src/modules/custom-validation/dto/custom-validation.dto.ts +132 -0
  64. package/templates/cqrs/src/modules/users/dto/user.dto.ts +64 -0
  65. package/templates/cqrs/src/modules/users/entities/user.entity.ts +9 -0
  66. package/templates/cqrs/src/modules/users/users.controller.ts +68 -0
  67. package/templates/cqrs/src/modules/users/users.module.ts +10 -0
  68. package/templates/cqrs/src/modules/users/users.service.ts +55 -0
  69. package/templates/cqrs/src/test-error-scenarios.ts +54 -0
  70. package/templates/cqrs/src/users/commands/create-user.command.ts +8 -0
  71. package/templates/cqrs/src/users/commands/index.ts +2 -0
  72. package/templates/cqrs/src/users/commands/update-user.command.ts +11 -0
  73. package/templates/cqrs/src/users/entities/index.ts +1 -0
  74. package/templates/cqrs/src/users/entities/user.entity.ts +22 -0
  75. package/templates/cqrs/src/users/events/index.ts +2 -0
  76. package/templates/cqrs/src/users/events/user-created.event.ts +8 -0
  77. package/templates/cqrs/src/users/events/user-updated.event.ts +8 -0
  78. package/templates/cqrs/src/users/handlers/create-user.handler.ts +26 -0
  79. package/templates/cqrs/src/users/handlers/get-all-users.handler.ts +15 -0
  80. package/templates/cqrs/src/users/handlers/get-user.handler.ts +15 -0
  81. package/templates/cqrs/src/users/handlers/index.ts +6 -0
  82. package/templates/cqrs/src/users/handlers/update-user.handler.ts +33 -0
  83. package/templates/cqrs/src/users/handlers/user-created.handler.ts +15 -0
  84. package/templates/cqrs/src/users/handlers/user-updated.handler.ts +15 -0
  85. package/templates/cqrs/src/users/index.ts +8 -0
  86. package/templates/cqrs/src/users/queries/get-all-users.query.ts +8 -0
  87. package/templates/cqrs/src/users/queries/get-user.query.ts +12 -0
  88. package/templates/cqrs/src/users/queries/index.ts +2 -0
  89. package/templates/cqrs/src/users/repositories/index.ts +1 -0
  90. package/templates/cqrs/src/users/repositories/user.repository.ts +51 -0
  91. package/templates/cqrs/src/users/user.controller.ts +66 -0
  92. package/templates/cqrs/src/users/user.module.ts +30 -0
  93. package/templates/cqrs/tsconfig.json +19 -0
  94. package/templates/cqrs_scalar/.prettierrc +33 -0
  95. package/templates/cqrs_scalar/.vscode/extensions.json +79 -0
  96. package/templates/cqrs_scalar/.vscode/settings.json +70 -0
  97. package/templates/cqrs_scalar/README.md +234 -0
  98. package/templates/cqrs_scalar/eslint.config.ts +26 -0
  99. package/templates/cqrs_scalar/package.json +62 -0
  100. package/templates/cqrs_scalar/src/app.controller.ts +28 -0
  101. package/templates/cqrs_scalar/src/app.module.ts +12 -0
  102. package/templates/cqrs_scalar/src/app.service.ts +8 -0
  103. package/templates/cqrs_scalar/src/common/filters/http-exception.filter.ts +34 -0
  104. package/templates/cqrs_scalar/src/common/interceptors/response.interceptor.ts +38 -0
  105. package/templates/cqrs_scalar/src/index.ts +38 -0
  106. package/templates/cqrs_scalar/src/modules/custom-validation/custom-validation.controller.ts +146 -0
  107. package/templates/cqrs_scalar/src/modules/custom-validation/custom-validation.module.ts +10 -0
  108. package/templates/cqrs_scalar/src/modules/custom-validation/custom-validation.service.ts +33 -0
  109. package/templates/cqrs_scalar/src/modules/custom-validation/dto/custom-validation.dto.ts +132 -0
  110. package/templates/cqrs_scalar/src/modules/users/dto/user.dto.ts +64 -0
  111. package/templates/cqrs_scalar/src/modules/users/entities/user.entity.ts +9 -0
  112. package/templates/cqrs_scalar/src/modules/users/users.controller.ts +68 -0
  113. package/templates/cqrs_scalar/src/modules/users/users.module.ts +10 -0
  114. package/templates/cqrs_scalar/src/modules/users/users.service.ts +55 -0
  115. package/templates/cqrs_scalar/src/test-error-scenarios.ts +54 -0
  116. package/templates/cqrs_scalar/src/users/commands/create-user.command.ts +8 -0
  117. package/templates/cqrs_scalar/src/users/commands/index.ts +2 -0
  118. package/templates/cqrs_scalar/src/users/commands/update-user.command.ts +11 -0
  119. package/templates/cqrs_scalar/src/users/entities/index.ts +1 -0
  120. package/templates/cqrs_scalar/src/users/entities/user.entity.ts +22 -0
  121. package/templates/cqrs_scalar/src/users/events/index.ts +2 -0
  122. package/templates/cqrs_scalar/src/users/events/user-created.event.ts +8 -0
  123. package/templates/cqrs_scalar/src/users/events/user-updated.event.ts +8 -0
  124. package/templates/cqrs_scalar/src/users/handlers/create-user.handler.ts +26 -0
  125. package/templates/cqrs_scalar/src/users/handlers/get-all-users.handler.ts +15 -0
  126. package/templates/cqrs_scalar/src/users/handlers/get-user.handler.ts +15 -0
  127. package/templates/cqrs_scalar/src/users/handlers/index.ts +6 -0
  128. package/templates/cqrs_scalar/src/users/handlers/update-user.handler.ts +33 -0
  129. package/templates/cqrs_scalar/src/users/handlers/user-created.handler.ts +15 -0
  130. package/templates/cqrs_scalar/src/users/handlers/user-updated.handler.ts +15 -0
  131. package/templates/cqrs_scalar/src/users/index.ts +8 -0
  132. package/templates/cqrs_scalar/src/users/queries/get-all-users.query.ts +8 -0
  133. package/templates/cqrs_scalar/src/users/queries/get-user.query.ts +12 -0
  134. package/templates/cqrs_scalar/src/users/queries/index.ts +2 -0
  135. package/templates/cqrs_scalar/src/users/repositories/index.ts +1 -0
  136. package/templates/cqrs_scalar/src/users/repositories/user.repository.ts +51 -0
  137. package/templates/cqrs_scalar/src/users/user.controller.ts +66 -0
  138. package/templates/cqrs_scalar/src/users/user.module.ts +30 -0
  139. package/templates/cqrs_scalar/tsconfig.json +19 -0
@@ -0,0 +1,562 @@
1
+ # HestJS Demo Application 🚀
2
+
3
+ 一个基于 **HestJS** 框架的现代化 TypeScript 演示应用,展示了类似 NestJS 的开发体验,但具有更轻量和更高性能的特点。内置支持通过注解自动生成 **OpenAPI 3.0** 规范的 Swagger 文档。
4
+
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
6
+ [![Bun](https://img.shields.io/badge/Bun-latest-orange.svg)](https://bun.sh/)
7
+ [![Hono](https://img.shields.io/badge/Hono-4.x-green.svg)](https://hono.dev/)
8
+ [![OpenAPI](https://img.shields.io/badge/OpenAPI-3.0-brightgreen.svg)](https://swagger.io/specification/)
9
+ [![Scalar](https://img.shields.io/badge/Scalar-API%20Docs-purple.svg)](https://scalar.com/)
10
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
11
+
12
+ ## ✨ 主要特性
13
+
14
+ - 🎯 **类 NestJS 语法**:熟悉的装饰器和模块化架构
15
+ - ⚡ **极致性能**:基于 Hono 和 Bun,提供卓越的运行时性能
16
+ - 📚 **自动 API 文档**:通过注解自动生成 OpenAPI 3.0 规范
17
+ - 🎨 **美观文档界面**:集成 Scalar,提供现代化的 API 文档体验
18
+ - 🔧 **依赖注入**:完整的 IoC 容器支持
19
+ - 🛡️ **类型安全**:完全的 TypeScript 支持
20
+ - 🚀 **快速开发**:热重载和快速构建
21
+
22
+ ## 📖 API 文档
23
+
24
+ 本应用集成了强大的 API 文档功能,支持通过注解自动生成符合 OpenAPI 3.0 规范的 Swagger 文档:
25
+
26
+ ### 🌐 在线访问
27
+
28
+ 启动应用后,可通过以下地址访问 API 文档:
29
+
30
+ - **📱 Scalar UI**: [http://localhost:3002/docs](http://localhost:3002/docs) - 现代化的交互式 API 文档界面
31
+ - **📄 OpenAPI JSON**: [http://localhost:3002/openapi.json](http://localhost:3002/openapi.json) - 原始 OpenAPI 3.0 规范文件
32
+ - **🤖 Markdown**: [http://localhost:3002/api-docs.md](http://localhost:3002/api-docs.md) - 为 LLM 优化的 Markdown 格式文档
33
+
34
+ ### 🔧 注解支持
35
+
36
+ 使用简单的装饰器即可为你的 API 生成完整的文档:
37
+
38
+ #### 控制器级别注解
39
+
40
+ ```typescript
41
+ import { Controller, Get, Post } from '@hestjs/core';
42
+ import { ApiTags, ApiOperation, ApiResponse } from '@hestjs/scalar';
43
+
44
+ @Controller('/api/users')
45
+ @ApiTags('Users') // 为控制器添加标签
46
+ export class UsersController {
47
+ // ...
48
+ }
49
+ ```
50
+
51
+ #### 方法级别注解
52
+
53
+ ```typescript
54
+ @Get('/')
55
+ @ApiOperation({
56
+ summary: 'Get all users',
57
+ description: 'Returns a list of all users in the system',
58
+ tags: ['Users', 'List'], // 可以覆盖控制器级别的标签
59
+ })
60
+ @ApiResponse('200', {
61
+ description: 'Successful response',
62
+ content: {
63
+ 'application/json': {
64
+ schema: {
65
+ type: 'array',
66
+ items: {
67
+ type: 'object',
68
+ properties: {
69
+ id: { type: 'string', example: 'user-123' },
70
+ name: { type: 'string', example: 'John Doe' },
71
+ email: { type: 'string', format: 'email', example: 'john@example.com' },
72
+ },
73
+ },
74
+ },
75
+ },
76
+ },
77
+ })
78
+ async getUsers() {
79
+ return this.usersService.findAll();
80
+ }
81
+ ```
82
+
83
+ #### 参数注解
84
+
85
+ ```typescript
86
+ @Get('/:id')
87
+ @ApiParam('id', {
88
+ description: 'User unique identifier',
89
+ schema: { type: 'string' },
90
+ example: 'user-123',
91
+ })
92
+ @ApiResponse('200', {
93
+ description: 'User found',
94
+ content: {
95
+ 'application/json': {
96
+ schema: {
97
+ type: 'object',
98
+ properties: {
99
+ id: { type: 'string' },
100
+ name: { type: 'string' },
101
+ email: { type: 'string' },
102
+ },
103
+ },
104
+ },
105
+ },
106
+ })
107
+ @ApiResponse('404', {
108
+ description: 'User not found',
109
+ content: {
110
+ 'application/json': {
111
+ schema: {
112
+ type: 'object',
113
+ properties: {
114
+ message: { type: 'string', example: 'User not found' },
115
+ },
116
+ },
117
+ },
118
+ },
119
+ })
120
+ async getUserById(@Param('id') id: string) {
121
+ return this.usersService.findById(id);
122
+ }
123
+ ```
124
+
125
+ #### 请求体注解
126
+
127
+ ```typescript
128
+ @Post('/')
129
+ @ApiOperation({
130
+ summary: 'Create a new user',
131
+ description: 'Creates a new user with the provided data',
132
+ })
133
+ @ApiBody(
134
+ {
135
+ 'application/json': {
136
+ schema: {
137
+ type: 'object',
138
+ required: ['name', 'email'],
139
+ properties: {
140
+ name: { type: 'string', example: 'John Doe' },
141
+ email: {
142
+ type: 'string',
143
+ format: 'email',
144
+ example: 'john@example.com'
145
+ },
146
+ },
147
+ },
148
+ },
149
+ },
150
+ {
151
+ description: 'User creation data',
152
+ required: true,
153
+ }
154
+ )
155
+ @ApiResponse('201', {
156
+ description: 'User created successfully',
157
+ content: {
158
+ 'application/json': {
159
+ schema: {
160
+ type: 'object',
161
+ properties: {
162
+ id: { type: 'string' },
163
+ name: { type: 'string' },
164
+ email: { type: 'string' },
165
+ createdAt: { type: 'string', format: 'date-time' },
166
+ },
167
+ },
168
+ },
169
+ },
170
+ })
171
+ async createUser(@Body() userData: CreateUserDto) {
172
+ return this.usersService.create(userData);
173
+ }
174
+ ```
175
+
176
+ ### 🎨 可用装饰器
177
+
178
+ | 装饰器 | 用途 | 示例 |
179
+ |--------|------|------|
180
+ | `@ApiTags(...)` | 为控制器或方法添加标签 | `@ApiTags('Users', 'Admin')` |
181
+ | `@ApiOperation(...)` | 描述 API 操作 | `@ApiOperation({ summary: '获取用户' })` |
182
+ | `@ApiResponse(status, spec)` | 定义响应格式 | `@ApiResponse('200', { description: '成功' })` |
183
+ | `@ApiParam(name, spec)` | 描述路径参数 | `@ApiParam('id', { type: 'string' })` |
184
+ | `@ApiQuery(name, spec)` | 描述查询参数 | `@ApiQuery('page', { type: 'number' })` |
185
+ | `@ApiBody(schema, options)` | 描述请求体 | `@ApiBody({ schema: userSchema })` |
186
+
187
+ ### ⚙️ 配置选项
188
+
189
+ ```typescript
190
+ // 在 main.ts 中配置 API 文档
191
+ app.useScalarWithControllers(
192
+ [AppController, UsersController], // 需要生成文档的控制器
193
+ {
194
+ // OpenAPI 基本信息
195
+ info: {
196
+ title: 'HestJS Demo API',
197
+ version: '1.0.0',
198
+ description: 'HestJS 框架演示应用的 API 文档',
199
+ contact: {
200
+ name: 'API Support',
201
+ email: 'support@example.com',
202
+ },
203
+ license: {
204
+ name: 'MIT',
205
+ url: 'https://opensource.org/licenses/MIT',
206
+ },
207
+ },
208
+ // 服务器配置
209
+ servers: [
210
+ {
211
+ url: 'http://localhost:3002',
212
+ description: 'Development server',
213
+ },
214
+ {
215
+ url: 'https://api.example.com',
216
+ description: 'Production server',
217
+ },
218
+ ],
219
+ },
220
+ {
221
+ // Scalar 配置
222
+ path: '/docs', // 文档访问路径
223
+ theme: 'elysia', // 主题样式
224
+ title: 'HestJS API Documentation', // 页面标题
225
+ enableMarkdown: true, // 启用 Markdown 导出
226
+ markdownPath: '/api-docs.md', // Markdown 访问路径
227
+ }
228
+ );
229
+ ```
230
+
231
+ ## 🏗️ 项目结构
232
+
233
+ ```
234
+ src/
235
+ ├── index.ts # 应用入口点
236
+ ├── app.module.ts # 根模块
237
+ ├── app.controller.ts # 应用控制器(含 API 文档注解示例)
238
+ ├── app.service.ts # 应用服务
239
+ ├── common/ # 公共组件
240
+ │ ├── filters/ # 全局过滤器
241
+ │ │ └── http-exception.filter.ts
242
+ │ └── interceptors/ # 全局拦截器
243
+ │ └── response.interceptor.ts
244
+ └── modules/ # 功能模块
245
+ ├── users/ # 用户模块
246
+ │ ├── dto/ # 数据传输对象
247
+ │ │ └── user.dto.ts
248
+ │ ├── users.controller.ts # 用户控制器(含完整 API 注解)
249
+ │ ├── users.service.ts
250
+ │ └── users.module.ts
251
+ └── custom-validation/ # 自定义验证模块
252
+ ├── dto/
253
+ │ └── custom-validation.dto.ts
254
+ ├── custom-validation.controller.ts
255
+ ├── custom-validation.service.ts
256
+ └── custom-validation.module.ts
257
+ ```
258
+
259
+ ## 🚀 快速开始
260
+
261
+ ### 前置要求
262
+
263
+ - [Bun](https://bun.sh/) >= 1.0.0
264
+ - Node.js >= 18.0.0 (可选,Bun 包含 Node.js 兼容层)
265
+
266
+ ### 安装依赖
267
+
268
+ ```bash
269
+ bun install
270
+ ```
271
+
272
+ ### 开发环境
273
+
274
+ ```bash
275
+ # 开发模式(热重载)
276
+ bun run dev
277
+
278
+ # 或者在 monorepo 根目录
279
+ turbo run dev --filter=@hestjs/demo
280
+ ```
281
+
282
+ ### 构建和部署
283
+
284
+ ```bash
285
+ # 构建
286
+ bun run build
287
+
288
+ # 生产环境运行
289
+ bun run start:prod
290
+
291
+ # 创建独立可执行文件
292
+ bun run build:binary
293
+ ./dist/hest-demo
294
+ ```
295
+
296
+ ## 📡 API 文档
297
+
298
+ ### 基础端点
299
+
300
+ - `GET /api` - 应用信息
301
+ - `GET /api/health` - 健康检查
302
+
303
+ ### 用户管理 (`/users`)
304
+
305
+ - `GET /users` - 获取所有用户
306
+ - `GET /users/:id` - 获取特定用户
307
+ - `POST /users` - 创建新用户
308
+ - `POST /users/:id` - 更新用户信息
309
+
310
+ #### 请求示例:
311
+
312
+ ```bash
313
+ # 创建用户
314
+ curl -X POST http://localhost:3002/users \
315
+ -H "Content-Type: application/json" \
316
+ -d '{
317
+ "name": "John Doe",
318
+ "email": "john@example.com",
319
+ "age": 30,
320
+ "password": "password123"
321
+ }'
322
+ ```
323
+
324
+ ### 自定义验证 (`/api/custom`)
325
+
326
+ - `GET /api/custom` - 验证功能说明
327
+ - `POST /api/custom/validate` - 测试自定义验证
328
+ - `POST /api/custom/search` - 测试搜索参数验证
329
+ - `GET /api/custom/examples` - 获取验证示例
330
+
331
+ #### 请求示例:
332
+
333
+ ```bash
334
+ # 自定义验证
335
+ curl -X POST http://localhost:3002/api/custom/validate \
336
+ -H "Content-Type: application/json" \
337
+ -d '{
338
+ "username": "john_doe123",
339
+ "role": "user",
340
+ "userId": "123e4567-e89b-12d3-a456-426614174000",
341
+ "phoneNumber": "13812345678",
342
+ "location": { "lat": 39.9042, "lng": 116.4074 },
343
+ "emails": ["john@example.com", "john.doe@company.com"]
344
+ }'
345
+ ```
346
+
347
+ ## 🛠️ 核心功能
348
+
349
+ ### 1. 模块化架构
350
+
351
+ - **清晰的模块分离**:每个功能模块都有自己的控制器、服务、DTO 和实体
352
+ - **依赖注入**:使用 `@Injectable()` 和 `@Module()` 装饰器
353
+ - **模块导入/导出**:支持模块间的依赖关系
354
+
355
+ ### 2. 强类型验证
356
+
357
+ - **TypeBox 集成**:使用 TypeBox 进行运行时类型验证
358
+ - **自定义验证器**:支持复杂的业务逻辑验证
359
+ - **联合类型支持**:支持 TypeScript 的高级类型特性
360
+
361
+ ### 3. 中间件和拦截器
362
+
363
+ - **全局异常过滤器**:统一的错误处理
364
+ - **响应拦截器**:统一的响应格式
365
+ - **CORS 支持**:跨域资源共享配置
366
+ - **请求日志**:自动记录请求和响应
367
+
368
+ ### 4. 配置管理
369
+
370
+ - **环境变量支持**:通过 `.env` 文件配置
371
+ - **类型安全配置**:使用 TypeScript 确保配置的类型安全
372
+
373
+ ### 5. CQRS 支持
374
+
375
+ - **命令查询职责分离**:支持 CQRS 架构模式
376
+ - **事件驱动**:内置事件总线支持
377
+ - **命令和查询处理器**:独立的命令和查询处理逻辑
378
+ - **事件溯源**:支持事件驱动的业务逻辑
379
+
380
+ > 📝 **CQRS 演示应用**:完整的 CQRS 实现示例请参考 [HestJS CQRS Demo](https://github.com/aqz236/hestjs-cqrs-demo)
381
+
382
+ ## 🔧 验证功能展示
383
+
384
+ ### 基础验证
385
+
386
+ ```typescript
387
+ export class CreateUserDto {
388
+ @IsString({ minLength: 2, maxLength: 50 })
389
+ name!: string;
390
+
391
+ @IsEmail()
392
+ email!: string;
393
+
394
+ @IsNumber()
395
+ @Min(0)
396
+ @Max(120)
397
+ age!: number;
398
+ }
399
+ ```
400
+
401
+ ### 高级验证
402
+
403
+ ```typescript
404
+ export class CustomValidationDto {
405
+ // 正则表达式验证
406
+ @Custom(
407
+ Type.String({ minLength: 3, maxLength: 20, pattern: '^[a-zA-Z0-9_]+$' }),
408
+ { message: '用户名必须是3-20位字母、数字或下划线' },
409
+ )
410
+ username!: string;
411
+
412
+ // 联合类型验证
413
+ @Custom(
414
+ Type.Union([
415
+ Type.Literal('admin'),
416
+ Type.Literal('user'),
417
+ Type.Literal('guest'),
418
+ ]),
419
+ { message: '角色必须是 admin、user 或 guest' },
420
+ )
421
+ role!: 'admin' | 'user' | 'guest';
422
+
423
+ // UUID 验证
424
+ @CommonValidators.UUID()
425
+ userId!: string;
426
+
427
+ // 中国手机号验证
428
+ @Custom(SchemaFactory.chinesePhoneNumber(), { optional: true })
429
+ phoneNumber?: string;
430
+
431
+ // 嵌套对象验证
432
+ @Custom(
433
+ Type.Object({
434
+ lat: Type.Number({ minimum: -90, maximum: 90 }),
435
+ lng: Type.Number({ minimum: -180, maximum: 180 }),
436
+ }),
437
+ { optional: true },
438
+ )
439
+ location?: { lat: number; lng: number };
440
+ }
441
+ ```
442
+
443
+ ## 🎯 架构特点
444
+
445
+ ### 1. NestJS 风格的目录结构
446
+
447
+ - 模块化组织:每个功能模块独立管理
448
+ - 清晰的职责分离:控制器、服务、DTO、实体分离
449
+ - 可扩展性:易于添加新功能模块
450
+
451
+ ### 2. 现代 TypeScript 开发
452
+
453
+ - 严格的类型检查
454
+ - 装饰器模式
455
+ - 依赖注入
456
+ - 接口优先设计
457
+
458
+ ### 3. 高性能运行时
459
+
460
+ - Bun 运行时支持
461
+ - Hono 高性能 Web 框架
462
+ - 端口复用优化
463
+ - 生产环境优化
464
+
465
+ ### 4. CQRS 架构支持
466
+
467
+ - 命令查询职责分离模式
468
+ - 事件驱动架构
469
+ - 独立的读写模型
470
+ - 可扩展的处理器模式
471
+
472
+ > 🔗 **完整 CQRS 示例**:查看专门的 CQRS 演示应用 → [HestJS CQRS Demo](https://github.com/aqz236/hestjs-cqrs-demo)
473
+
474
+ ## 📦 部署
475
+
476
+ ### Docker 部署
477
+
478
+ ```dockerfile
479
+ FROM oven/bun:1 as base
480
+ WORKDIR /app
481
+
482
+ # 复制依赖文件
483
+ COPY package.json bun.lock ./
484
+ RUN bun install --frozen-lockfile
485
+
486
+ # 复制源代码
487
+ COPY . .
488
+
489
+ # 构建应用
490
+ RUN bun run build
491
+
492
+ # 运行应用
493
+ CMD ["bun", "run", "start:prod"]
494
+ EXPOSE 3002
495
+ ```
496
+
497
+ ### 二进制部署
498
+
499
+ ```bash
500
+ # 构建独立可执行文件
501
+ bun run build:binary
502
+
503
+ # 部署单个文件
504
+ ./dist/hest-demo
505
+ ```
506
+
507
+ ## 🧪 测试
508
+
509
+ ```bash
510
+ # 运行测试
511
+ bun test
512
+
513
+ # 覆盖率测试
514
+ bun test --coverage
515
+ ```
516
+
517
+ ## 📝 开发指南
518
+
519
+ ### 添加新模块
520
+
521
+ 1. 在 `src/modules/` 下创建新目录
522
+ 2. 创建 `*.module.ts`、`*.controller.ts`、`*.service.ts`
523
+ 3. 在 `app.module.ts` 中导入新模块
524
+
525
+ ### 添加验证规则
526
+
527
+ 1. 在模块的 `dto/` 目录下创建 DTO 类
528
+ 2. 使用 `@Custom()` 装饰器定义验证规则
529
+ 3. 在控制器中使用 `@Body()` 装饰器应用验证
530
+
531
+ ### 环境配置
532
+
533
+ ```bash
534
+ # .env 文件
535
+ PORT=3002
536
+ NODE_ENV=development
537
+ CORS_ORIGIN=*
538
+ ```
539
+
540
+ ## 🔗 相关项目
541
+
542
+ ### HestJS CQRS Demo
543
+
544
+ 完整的 CQRS(命令查询职责分离)架构演示应用,展示了如何在 HestJS 框架中实现:
545
+
546
+ - ✅ 命令处理器 (Command Handlers)
547
+ - ✅ 查询处理器 (Query Handlers)
548
+ - ✅ 事件处理器 (Event Handlers)
549
+ - ✅ 事件总线 (Event Bus)
550
+ - ✅ 用户管理完整流程
551
+
552
+ 🔗 **仓库地址**:[https://github.com/aqz236/hestjs-cqrs-demo](https://github.com/aqz236/hestjs-cqrs-demo)
553
+
554
+ 该项目展示了在现代 TypeScript 应用中如何优雅地实现 CQRS 模式,适合需要复杂业务逻辑和高可扩展性的企业级应用。
555
+
556
+ ## 🤝 贡献
557
+
558
+ 欢迎提交 Issue 和 Pull Request!
559
+
560
+ ## 📄 许可证
561
+
562
+ MIT License
@@ -0,0 +1,26 @@
1
+ import wfConfig from '@hestjs/eslint-config';
2
+
3
+ export default [
4
+ ...wfConfig,
5
+ {
6
+ files: ['**/*.ts', '**/*.tsx'],
7
+ rules: {
8
+ 'no-console': 'error', // Demo 应用允许使用 console 进行调试
9
+ },
10
+ },
11
+ {
12
+ // 忽略构建产物和临时文件
13
+ ignores: [
14
+ 'node_modules/**',
15
+ 'dist/**',
16
+ 'build/**',
17
+ '*.d.ts',
18
+ '.bun/**',
19
+ 'bun.lockb',
20
+ // shadcn 目录
21
+ 'src/components/ui/**',
22
+ // scripts 目录
23
+ 'scripts/**',
24
+ ],
25
+ },
26
+ ];
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@hestjs/demo",
3
+ "version": "0.1.1",
4
+ "description": "HestJS Demo Application - A demonstration of HestJS framework capabilities",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "scripts": {
12
+ "dev": "bun run --hot src/index.ts",
13
+ "build": "bun build src/index.ts --outdir=dist --target=bun --format=esm --splitting --external pino --external pino-pretty --external sonic-boom --external thread-stream",
14
+ "build:external": "bun build src/index.ts --outdir=dist --target=bun --format=esm --external reflect-metadata --external pino --external pino-pretty --external sonic-boom --external thread-stream",
15
+ "build:binary": "bun build src/index.ts --compile --outfile=dist/hest-demo --external pino-pretty",
16
+ "start": "bun run dist/index.js | pino-pretty",
17
+ "start:binary": "./dist/hest-demo | pino-pretty",
18
+ "start:prod": "NODE_ENV=production bun run dist/index.js | pino-pretty",
19
+ "clean": "rm -rf dist",
20
+ "check-types": "tsc --noEmit"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/aqz236/hestjs-demo.git"
25
+ },
26
+ "homepage": "https://github.com/aqz236/hestjs-demo#readme",
27
+ "bugs": {
28
+ "url": "https://github.com/aqz236/hestjs-demo/issues"
29
+ },
30
+ "author": "aqz236",
31
+ "license": "MIT",
32
+ "dependencies": {
33
+ "@hestjs/core": "^0.1.8",
34
+ "@hestjs/logger": "^0.1.5",
35
+ "@hestjs/scalar": "^0.1.2",
36
+ "@hestjs/validation": "^0.1.5",
37
+ "hono": "^4.8.9",
38
+ "reflect-metadata": "^0.2.2"
39
+ },
40
+ "devDependencies": {
41
+ "@hestjs/eslint-config": "^0.1.1",
42
+ "@hestjs/typescript-config": "^0.1.0",
43
+ "@types/bun": "^1.2.19",
44
+ "jiti": "^2.5.1",
45
+ "typescript": "5.8.3"
46
+ },
47
+ "exports": {
48
+ ".": {
49
+ "import": "./dist/index.js",
50
+ "require": "./dist/index.js",
51
+ "types": "./dist/index.d.ts"
52
+ }
53
+ },
54
+ "keywords": [
55
+ "hestjs",
56
+ "demo",
57
+ "framework",
58
+ "typescript",
59
+ "bun",
60
+ "hono",
61
+ "validation"
62
+ ]
63
+ }