@hestjs/demo 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.
- package/README.md +387 -0
- package/dist/index.js +18829 -0
- package/package.json +61 -0
package/README.md
ADDED
@@ -0,0 +1,387 @@
|
|
1
|
+
# HestJS 🚀
|
2
|
+
|
3
|
+
一个基于 **Hono + Bun + TSyringe** 的现代化 TypeScript 后端框架,提供类似 NestJS 的开发体验,但具有更轻量和更高性能的特点。
|
4
|
+
|
5
|
+
[](https://www.typescriptlang.org/)
|
6
|
+
[](https://bun.sh/)
|
7
|
+
[](https://hono.dev/)
|
8
|
+
[](LICENSE)
|
9
|
+
|
10
|
+
## ✨ 特性
|
11
|
+
|
12
|
+
- 🎯 **装饰器驱动** - 使用装饰器定义控制器、服务、中间件
|
13
|
+
- 💉 **依赖注入** - 基于 TSyringe 的完整 DI 容器,用户透明
|
14
|
+
- 🏗️ **模块化架构** - 采用模块系统组织代码
|
15
|
+
- ⚡ **高性能** - 基于 Hono 和 Bun 获得最佳性能
|
16
|
+
- 🔒 **类型安全** - 完全的 TypeScript 支持
|
17
|
+
- 🛡️ **验证系统** - 基于 TypeBox 的强大验证功能
|
18
|
+
- 🔄 **拦截器** - 灵活的请求/响应拦截机制
|
19
|
+
- 🚨 **异常处理** - 完善的异常过滤和处理系统
|
20
|
+
|
21
|
+
## 🚀 快速开始
|
22
|
+
|
23
|
+
### 安装
|
24
|
+
|
25
|
+
```bash
|
26
|
+
# 克隆项目
|
27
|
+
git clone https://github.com/aqz236/hest.git
|
28
|
+
cd HestJS
|
29
|
+
|
30
|
+
# 安装依赖
|
31
|
+
bun install
|
32
|
+
|
33
|
+
# 构建包
|
34
|
+
bun run build
|
35
|
+
|
36
|
+
# 运行示例应用
|
37
|
+
cd apps/hest-demo
|
38
|
+
bun run dev
|
39
|
+
```
|
40
|
+
|
41
|
+
### 创建你的第一个应用
|
42
|
+
|
43
|
+
```typescript
|
44
|
+
// app.controller.ts
|
45
|
+
import { Controller, Get, Post, Body } from "@hestjs/core";
|
46
|
+
import { IsString, IsEmail, IsNumber } from "@hestjs/validation";
|
47
|
+
|
48
|
+
export class CreateUserDto {
|
49
|
+
@IsString({ minLength: 2, maxLength: 50 })
|
50
|
+
name!: string;
|
51
|
+
|
52
|
+
@IsEmail()
|
53
|
+
email!: string;
|
54
|
+
|
55
|
+
@IsNumber({ minimum: 0, maximum: 120 })
|
56
|
+
age!: number;
|
57
|
+
}
|
58
|
+
|
59
|
+
@Controller("/api")
|
60
|
+
export class AppController {
|
61
|
+
@Get("/users")
|
62
|
+
getUsers() {
|
63
|
+
return { users: [] };
|
64
|
+
}
|
65
|
+
|
66
|
+
@Post("/users")
|
67
|
+
createUser(@Body(CreateUserDto) createUserDto: CreateUserDto) {
|
68
|
+
// createUserDto 已经过验证和类型转换
|
69
|
+
return { success: true, data: createUserDto };
|
70
|
+
}
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
```typescript
|
75
|
+
// app.module.ts
|
76
|
+
import { Module } from "@hestjs/core";
|
77
|
+
import { AppController } from "./app.controller";
|
78
|
+
|
79
|
+
@Module({
|
80
|
+
controllers: [AppController],
|
81
|
+
})
|
82
|
+
export class AppModule {}
|
83
|
+
```
|
84
|
+
|
85
|
+
```typescript
|
86
|
+
// main.ts
|
87
|
+
import { HestFactory } from "@hestjs/core";
|
88
|
+
import { ValidationInterceptor } from "@hestjs/validation";
|
89
|
+
import { AppModule } from "./app.module";
|
90
|
+
|
91
|
+
async function bootstrap() {
|
92
|
+
const app = await HestFactory.create(AppModule);
|
93
|
+
|
94
|
+
// 启用全局验证
|
95
|
+
app.useGlobalInterceptors(new ValidationInterceptor());
|
96
|
+
|
97
|
+
await app.listen(3000);
|
98
|
+
console.log("🚀 Application is running on: http://localhost:3000");
|
99
|
+
}
|
100
|
+
|
101
|
+
bootstrap();
|
102
|
+
```
|
103
|
+
|
104
|
+
## 📁 项目结构
|
105
|
+
|
106
|
+
```
|
107
|
+
packages/
|
108
|
+
├── core/ # 核心框架包
|
109
|
+
│ ├── decorators/ # 装饰器定义
|
110
|
+
│ ├── interfaces/ # 核心接口
|
111
|
+
│ ├── application/ # 应用核心
|
112
|
+
│ └── exceptions/ # 异常处理
|
113
|
+
├── validation/ # 验证模块
|
114
|
+
│ ├── decorators/ # 验证装饰器
|
115
|
+
│ ├── pipes/ # 验证管道
|
116
|
+
│ └── interceptors/ # 验证拦截器
|
117
|
+
└── ...
|
118
|
+
```
|
119
|
+
|
120
|
+
## 🎯 核心概念
|
121
|
+
|
122
|
+
### 控制器 (Controllers)
|
123
|
+
|
124
|
+
```typescript
|
125
|
+
@Controller("/users")
|
126
|
+
export class UserController {
|
127
|
+
@Get("/")
|
128
|
+
findAll() {
|
129
|
+
return { users: [] };
|
130
|
+
}
|
131
|
+
|
132
|
+
@Get("/:id")
|
133
|
+
findOne(@Param("id") id: string) {
|
134
|
+
return { user: { id } };
|
135
|
+
}
|
136
|
+
|
137
|
+
@Post("/")
|
138
|
+
create(@Body(CreateUserDto) createUserDto: CreateUserDto) {
|
139
|
+
return { success: true };
|
140
|
+
}
|
141
|
+
}
|
142
|
+
```
|
143
|
+
|
144
|
+
### 服务和依赖注入 (Services & DI)
|
145
|
+
|
146
|
+
```typescript
|
147
|
+
@Injectable()
|
148
|
+
export class UserService {
|
149
|
+
async findAll() {
|
150
|
+
return [];
|
151
|
+
}
|
152
|
+
|
153
|
+
async create(userData: any) {
|
154
|
+
// 创建用户逻辑
|
155
|
+
return userData;
|
156
|
+
}
|
157
|
+
}
|
158
|
+
|
159
|
+
@Controller("/users")
|
160
|
+
export class UserController {
|
161
|
+
constructor(private readonly userService: UserService) {}
|
162
|
+
|
163
|
+
@Get("/")
|
164
|
+
async findAll() {
|
165
|
+
return await this.userService.findAll();
|
166
|
+
}
|
167
|
+
}
|
168
|
+
```
|
169
|
+
|
170
|
+
### 验证系统 (Validation)
|
171
|
+
|
172
|
+
#### 基础验证装饰器
|
173
|
+
|
174
|
+
```typescript
|
175
|
+
export class CreateUserDto {
|
176
|
+
@IsString({ minLength: 2, maxLength: 50 })
|
177
|
+
name!: string;
|
178
|
+
|
179
|
+
@IsEmail()
|
180
|
+
email!: string;
|
181
|
+
|
182
|
+
@IsNumber({ minimum: 18, maximum: 100 })
|
183
|
+
age!: number;
|
184
|
+
|
185
|
+
@IsOptional()
|
186
|
+
@IsString()
|
187
|
+
bio?: string;
|
188
|
+
}
|
189
|
+
```
|
190
|
+
|
191
|
+
#### 自定义验证 (TypeBox API)
|
192
|
+
|
193
|
+
```typescript
|
194
|
+
import { Type } from "@sinclair/typebox";
|
195
|
+
import { Custom, CommonValidators, SchemaFactory } from "@hestjs/validation";
|
196
|
+
|
197
|
+
export class AdvancedDto {
|
198
|
+
// 使用 TypeBox API 自定义验证
|
199
|
+
@Custom(
|
200
|
+
Type.String({
|
201
|
+
minLength: 3,
|
202
|
+
maxLength: 20,
|
203
|
+
pattern: "^[a-zA-Z0-9_]+$",
|
204
|
+
})
|
205
|
+
)
|
206
|
+
username!: string;
|
207
|
+
|
208
|
+
// 使用联合类型
|
209
|
+
@Custom(
|
210
|
+
Type.Union([
|
211
|
+
Type.Literal("admin"),
|
212
|
+
Type.Literal("user"),
|
213
|
+
Type.Literal("guest"),
|
214
|
+
])
|
215
|
+
)
|
216
|
+
role!: "admin" | "user" | "guest";
|
217
|
+
|
218
|
+
// 使用常用验证器
|
219
|
+
@CommonValidators.UUID()
|
220
|
+
userId!: string;
|
221
|
+
|
222
|
+
// 使用便捷构建器
|
223
|
+
@Custom(SchemaFactory.chinesePhoneNumber())
|
224
|
+
phoneNumber!: string;
|
225
|
+
|
226
|
+
// 复杂对象验证
|
227
|
+
@Custom(
|
228
|
+
Type.Object({
|
229
|
+
lat: Type.Number({ minimum: -90, maximum: 90 }),
|
230
|
+
lng: Type.Number({ minimum: -180, maximum: 180 }),
|
231
|
+
})
|
232
|
+
)
|
233
|
+
location!: { lat: number; lng: number };
|
234
|
+
}
|
235
|
+
```
|
236
|
+
|
237
|
+
### 拦截器 (Interceptors)
|
238
|
+
|
239
|
+
```typescript
|
240
|
+
import { Interceptor, ExecutionContext, CallHandler } from "@hestjs/core";
|
241
|
+
|
242
|
+
export class LoggingInterceptor implements Interceptor {
|
243
|
+
intercept(context: ExecutionContext, next: CallHandler) {
|
244
|
+
console.log("Before...");
|
245
|
+
|
246
|
+
const now = Date.now();
|
247
|
+
return next.handle().then(() => {
|
248
|
+
console.log(`After... ${Date.now() - now}ms`);
|
249
|
+
});
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
// 使用拦截器
|
254
|
+
app.useGlobalInterceptors(new LoggingInterceptor());
|
255
|
+
```
|
256
|
+
|
257
|
+
### 异常处理 (Exception Handling)
|
258
|
+
|
259
|
+
```typescript
|
260
|
+
import {
|
261
|
+
HttpException,
|
262
|
+
NotFoundException,
|
263
|
+
BadRequestException,
|
264
|
+
} from "@hestjs/core";
|
265
|
+
|
266
|
+
@Controller("/users")
|
267
|
+
export class UserController {
|
268
|
+
@Get("/:id")
|
269
|
+
findOne(@Param("id") id: string) {
|
270
|
+
const user = this.findUserById(id);
|
271
|
+
if (!user) {
|
272
|
+
throw new NotFoundException(`User with id ${id} not found`);
|
273
|
+
}
|
274
|
+
return user;
|
275
|
+
}
|
276
|
+
|
277
|
+
@Post("/")
|
278
|
+
create(@Body() userData: any) {
|
279
|
+
if (!userData.email) {
|
280
|
+
throw new BadRequestException("Email is required");
|
281
|
+
}
|
282
|
+
return this.createUser(userData);
|
283
|
+
}
|
284
|
+
}
|
285
|
+
```
|
286
|
+
|
287
|
+
## 🔧 开发状态
|
288
|
+
|
289
|
+
### ✅ 已完成功能
|
290
|
+
|
291
|
+
- **Phase 1: 核心基础设施** ✅
|
292
|
+
- 装饰器系统 (`@Controller`, `@Injectable`, `@Module`, 路由装饰器)
|
293
|
+
- 依赖注入容器 (基于 TSyringe)
|
294
|
+
- 应用工厂 (`HestFactory.create()`)
|
295
|
+
- 路由系统和参数注入
|
296
|
+
|
297
|
+
- **Phase 2: 中间件和异常处理** ✅
|
298
|
+
- 异常处理系统 (HttpException, 异常过滤器)
|
299
|
+
- 拦截器系统 (Interceptor, ExecutionContext)
|
300
|
+
- 全局拦截器和异常过滤器支持
|
301
|
+
|
302
|
+
- **Phase 3: 验证系统** ✅
|
303
|
+
- 基于 TypeBox 的验证装饰器
|
304
|
+
- @Custom() 装饰器支持完整 TypeBox API
|
305
|
+
- ValidationInterceptor 自动验证
|
306
|
+
- SchemaFactory 和 CommonValidators
|
307
|
+
- 详细验证错误处理
|
308
|
+
|
309
|
+
### 🚧 开发中
|
310
|
+
|
311
|
+
- **Phase 4: 配置和日志系统**
|
312
|
+
- **Phase 5: 高级拦截器和管道**
|
313
|
+
- **Phase 6: CLI 工具**
|
314
|
+
|
315
|
+
## 📊 性能
|
316
|
+
|
317
|
+
基于 Bun 运行时和 Hono 框架,HestJS 提供了卓越的性能:
|
318
|
+
|
319
|
+
- 🚀 **快速启动** - 得益于 Bun 的快速启动时间
|
320
|
+
- ⚡ **高吞吐量** - Hono 的高效路由和中间件系统
|
321
|
+
- 💾 **低内存占用** - 轻量级架构设计
|
322
|
+
- 🔧 **编译时优化** - TypeScript 装饰器元数据预处理
|
323
|
+
|
324
|
+
## 🛠️ 开发
|
325
|
+
|
326
|
+
### 构建项目
|
327
|
+
|
328
|
+
```bash
|
329
|
+
# 安装依赖
|
330
|
+
bun install
|
331
|
+
|
332
|
+
# 构建所有包
|
333
|
+
bun run build
|
334
|
+
|
335
|
+
# 运行测试
|
336
|
+
bun run test
|
337
|
+
|
338
|
+
# 运行示例应用
|
339
|
+
cd apps/hest-demo
|
340
|
+
bun run dev
|
341
|
+
```
|
342
|
+
|
343
|
+
### 测试验证功能
|
344
|
+
|
345
|
+
```bash
|
346
|
+
# 运行 Phase 3 验证测试
|
347
|
+
bun test-phase3.ts
|
348
|
+
```
|
349
|
+
|
350
|
+
## 📖 API 参考
|
351
|
+
|
352
|
+
### 装饰器
|
353
|
+
|
354
|
+
- `@Controller(path?)` - 定义控制器
|
355
|
+
- `@Injectable()` - 标记可注入服务
|
356
|
+
- `@Module(options)` - 定义模块
|
357
|
+
- `@Get(path?)`, `@Post(path?)`, `@Put(path?)`, `@Delete(path?)` - HTTP 路由
|
358
|
+
- `@Body(dtoClass?)`, `@Param(key?)`, `@Query(key?)` - 参数注入
|
359
|
+
- `@IsString()`, `@IsEmail()`, `@IsNumber()` - 基础验证
|
360
|
+
- `@Custom(schema, options?)` - 自定义 TypeBox 验证
|
361
|
+
|
362
|
+
### 核心类
|
363
|
+
|
364
|
+
- `HestFactory` - 应用工厂
|
365
|
+
- `HttpException` - HTTP 异常基类
|
366
|
+
- `ValidationInterceptor` - 验证拦截器
|
367
|
+
- `Interceptor` - 拦截器接口
|
368
|
+
- `ExecutionContext` - 执行上下文
|
369
|
+
|
370
|
+
## 🤝 贡献
|
371
|
+
|
372
|
+
欢迎贡献代码!请查看 [贡献指南](CONTRIBUTING.md) 了解详情。
|
373
|
+
|
374
|
+
## 📄 许可证
|
375
|
+
|
376
|
+
[MIT](LICENSE)
|
377
|
+
|
378
|
+
## 🔗 相关链接
|
379
|
+
|
380
|
+
- [Hono](https://hono.dev/) - 快速、轻量级的 Web 框架
|
381
|
+
- [Bun](https://bun.sh/) - 快速的 JavaScript 运行时
|
382
|
+
- [TSyringe](https://github.com/microsoft/tsyringe) - 依赖注入容器
|
383
|
+
- [TypeBox](https://github.com/sinclairzx81/typebox) - JSON Schema 类型构建器
|
384
|
+
|
385
|
+
---
|
386
|
+
|
387
|
+
⭐ 如果这个项目对你有帮助,请给个 Star!
|