vafast 0.1.17 → 0.2.1
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 +167 -185
- package/dist/auth/token.d.ts +39 -2
- package/dist/auth/token.js +124 -0
- package/dist/defineRoute.js +3 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.js +13 -323
- package/dist/middleware/auth.d.ts +6 -0
- package/dist/middleware/auth.js +106 -0
- package/dist/middleware/authMiddleware.js +13 -0
- package/dist/middleware/component-renderer.d.ts +6 -0
- package/dist/middleware/component-renderer.js +132 -0
- package/dist/middleware/component-router.d.ts +10 -0
- package/dist/middleware/component-router.js +42 -0
- package/dist/middleware/cors.js +30 -0
- package/dist/middleware/rateLimit.js +33 -0
- package/dist/middleware.d.ts +1 -1
- package/dist/middleware.js +56 -0
- package/dist/monitoring/index.d.ts +29 -0
- package/dist/monitoring/index.js +24 -0
- package/dist/monitoring/native-monitor.d.ts +38 -0
- package/dist/monitoring/native-monitor.js +176 -0
- package/dist/monitoring/types.d.ts +146 -0
- package/dist/monitoring/types.js +8 -0
- package/dist/router/index.d.ts +5 -0
- package/dist/router/index.js +7 -0
- package/dist/router/radix-tree.d.ts +51 -0
- package/dist/router/radix-tree.js +186 -0
- package/dist/router.d.ts +43 -6
- package/dist/router.js +86 -0
- package/dist/server/base-server.d.ts +34 -0
- package/dist/server/base-server.js +145 -0
- package/dist/server/component-server.d.ts +32 -0
- package/dist/server/component-server.js +146 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +11 -0
- package/dist/server/server-factory.d.ts +42 -0
- package/dist/server/server-factory.js +70 -0
- package/dist/server/server.d.ts +35 -0
- package/dist/server/server.js +97 -0
- package/dist/types/component-route.d.ts +25 -0
- package/dist/types/component-route.js +1 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +4 -0
- package/dist/types/route.d.ts +39 -0
- package/dist/types/route.js +11 -0
- package/dist/types/schema.d.ts +75 -0
- package/dist/types/schema.js +10 -0
- package/dist/types/types.d.ts +22 -0
- package/dist/types/types.js +1 -0
- package/dist/utils/base64url.js +11 -0
- package/dist/utils/create-handler.d.ts +74 -0
- package/dist/utils/create-handler.js +234 -0
- package/dist/utils/dependency-manager.d.ts +23 -0
- package/dist/utils/dependency-manager.js +73 -0
- package/dist/utils/go-await.d.ts +26 -0
- package/dist/utils/go-await.js +30 -0
- package/dist/{cookie.d.ts → utils/handle.d.ts} +3 -0
- package/dist/utils/handle.js +29 -0
- package/dist/utils/html-renderer.d.ts +18 -0
- package/dist/utils/html-renderer.js +64 -0
- package/dist/utils/index.d.ts +12 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/parsers.d.ts +36 -0
- package/dist/utils/parsers.js +126 -0
- package/dist/utils/path-matcher.d.ts +23 -0
- package/dist/utils/path-matcher.js +83 -0
- package/dist/utils/request-validator.d.ts +63 -0
- package/dist/utils/request-validator.js +94 -0
- package/dist/utils/response.d.ts +17 -0
- package/dist/utils/response.js +110 -0
- package/dist/utils/validators/schema-validator.d.ts +66 -0
- package/dist/utils/validators/schema-validator.js +222 -0
- package/dist/utils/validators/schema-validators-ultra.d.ts +51 -0
- package/dist/utils/validators/schema-validators-ultra.js +289 -0
- package/dist/utils/validators/validators.d.ts +30 -0
- package/dist/utils/validators/validators.js +54 -0
- package/package.json +50 -14
- package/dist/server.d.ts +0 -9
- package/dist/types.d.ts +0 -9
- package/dist/util.d.ts +0 -7
package/README.md
CHANGED
|
@@ -1,237 +1,219 @@
|
|
|
1
|
-
# Vafast
|
|
2
|
-

|
|
3
|
-

|
|
4
|
-

|
|
5
|
-

|
|
6
|
-

|
|
1
|
+
# Vafast 🚀
|
|
7
2
|
|
|
3
|
+
> 超高性能的Node.js Web框架,专为Bun运行时设计
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
[](https://github.com/vafast/vafast/actions)
|
|
6
|
+
[](https://badge.fury.io/js/vafast)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://bun.sh/)
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
[](https://vafast.dev)
|
|
15
|
-
|
|
16
|
-
## 📚 Vafast 文档
|
|
17
|
-
|
|
18
|
-
探索Vafast的完整指南 — 一个专为速度、结构和零样板代码而构建的Bun和Edge原生Web框架。
|
|
19
|
-
|
|
20
|
-
👉 [https://vafast.dev](https://vafast.dev)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
> ⚡ 亚毫秒级API。一流的副作用控制。
|
|
25
|
-
> 👉 [在GitHub上给Vafast加星标](https://github.com/vafast/vafast)
|
|
26
|
-
Vafast是一个声明式、类型安全的Bun框架 — 旨在使副作用显式化,性能可预测。
|
|
27
|
-
|
|
28
|
-
---
|
|
29
|
-
|
|
30
|
-
## 🚀 快速开始
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npx create-vafast-app
|
|
34
|
-
```
|
|
10
|
+
一个专注于性能和易用性的现代Node.js Web框架,内置超优化的验证器和中间件系统。
|
|
35
11
|
|
|
36
|
-
|
|
12
|
+
## 🚀 核心特性
|
|
37
13
|
|
|
38
|
-
|
|
14
|
+
- **超高性能**: 基于优化的验证器和路由系统
|
|
15
|
+
- **类型安全**: 完整的TypeScript支持
|
|
16
|
+
- **中间件系统**: 灵活可扩展的中间件架构
|
|
17
|
+
- **内置验证**: 超优化的Schema验证器
|
|
18
|
+
- **零依赖**: 最小化外部依赖
|
|
39
19
|
|
|
40
|
-
|
|
41
|
-
* **Cloudflare Workers**
|
|
42
|
-
|
|
43
|
-
此命令在几秒钟内设置一个可立即运行的Vafast项目。
|
|
44
|
-
|
|
45
|
-
📣 **喜欢不碍事的极简工具?**
|
|
46
|
-
给主Vafast仓库加星标:[https://github.com/vafast/vafast](https://github.com/vafast/vafast)
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## 📁 您将获得什么
|
|
51
|
-
|
|
52
|
-
一个零样板项目,专为您的运行时定制:
|
|
53
|
-
|
|
54
|
-
* 带有工作路由器和`/`端点的`index.ts`
|
|
55
|
-
* 运行时配置文件(`bunfig.toml`、`wrangler.toml`)
|
|
56
|
-
* 带有最小脚本和依赖项的`package.json`
|
|
57
|
-
|
|
58
|
-
示例输出:
|
|
20
|
+
## 📦 安装
|
|
59
21
|
|
|
60
22
|
```bash
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
✅ Vafast应用已在'my-vafast-app'中创建
|
|
23
|
+
# 使用 bun (推荐)
|
|
24
|
+
bun add vafast
|
|
65
25
|
|
|
66
|
-
|
|
26
|
+
# 使用 npm
|
|
27
|
+
npm install vafast
|
|
67
28
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
npm run dev (Bun) # 或 wrangler dev
|
|
29
|
+
# 使用 yarn
|
|
30
|
+
yarn add vafast
|
|
71
31
|
```
|
|
72
32
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
33
|
+
## 🎯 快速开始
|
|
34
|
+
|
|
35
|
+
### 基础示例
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { createServer, defineRoute } from 'vafast';
|
|
39
|
+
import { Type } from '@sinclair/typebox';
|
|
40
|
+
|
|
41
|
+
// 定义路由Schema
|
|
42
|
+
const userSchema = Type.Object({
|
|
43
|
+
name: Type.String({ minLength: 1 }),
|
|
44
|
+
email: Type.String({ pattern: '^[^@]+@[^@]+\\.[^@]+$' }),
|
|
45
|
+
age: Type.Optional(Type.Number({ minimum: 0 }))
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// 创建路由
|
|
49
|
+
const userRoute = defineRoute({
|
|
50
|
+
method: 'POST',
|
|
51
|
+
path: '/users',
|
|
52
|
+
body: userSchema,
|
|
53
|
+
handler: async (req) => {
|
|
54
|
+
const { name, email, age } = req.body;
|
|
55
|
+
return { success: true, user: { name, email, age } };
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// 创建服务器
|
|
60
|
+
const server = createServer();
|
|
61
|
+
server.addRoute(userRoute);
|
|
62
|
+
|
|
63
|
+
server.listen(3000, () => {
|
|
64
|
+
console.log('🚀 服务器运行在 http://localhost:3000');
|
|
65
|
+
});
|
|
66
|
+
```
|
|
78
67
|
|
|
79
|
-
|
|
80
|
-
2. **错误即值** — VafastError携带类型、状态和意图。它们被抛出,但不被隐藏。
|
|
81
|
-
3. **组合优于约定** — 中间件被显式组合,顺序是契约的一部分。
|
|
82
|
-
4. **类型塑造行为** — 您的API的结构和安全性由其类型定义,而不是文档。
|
|
83
|
-
5. **专为边缘设计** — 为Bun构建,为fetch优化,诞生于毫秒时代。
|
|
68
|
+
### 使用超优化验证器
|
|
84
69
|
|
|
85
|
-
|
|
70
|
+
```typescript
|
|
71
|
+
import { validateAllSchemasExpanded } from 'vafast/utils/validators/validators-ultra';
|
|
86
72
|
|
|
87
|
-
|
|
73
|
+
// 定义Schema配置
|
|
74
|
+
const schemaConfig = {
|
|
75
|
+
body: userSchema,
|
|
76
|
+
query: querySchema,
|
|
77
|
+
params: paramsSchema,
|
|
78
|
+
headers: headersSchema,
|
|
79
|
+
cookies: cookiesSchema
|
|
80
|
+
};
|
|
88
81
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
82
|
+
// 验证请求数据
|
|
83
|
+
const validatedData = validateAllSchemasExpanded(schemaConfig, {
|
|
84
|
+
body: req.body,
|
|
85
|
+
query: req.query,
|
|
86
|
+
params: req.params,
|
|
87
|
+
headers: req.headers,
|
|
88
|
+
cookies: req.cookies
|
|
89
|
+
});
|
|
90
|
+
```
|
|
96
91
|
|
|
97
|
-
|
|
92
|
+
## 🔧 超优化验证器
|
|
98
93
|
|
|
99
|
-
|
|
94
|
+
### Ultra验证器
|
|
100
95
|
|
|
101
|
-
|
|
96
|
+
我们的旗舰验证器,提供极致性能:
|
|
102
97
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
| 🔁 请求/秒 | `90,489 rps` | 🔥 与Hono相当,超过Express 10倍+ |
|
|
108
|
-
| 📉 平均延迟 | `0.96 ms` | ⚡ 负载下亚毫秒 — 适用于交互式应用 |
|
|
109
|
-
| 📦 吞吐量 | `10.9 MB/sec` | 📈 轻松处理大型JSON负载 |
|
|
110
|
-
| 🎯 总请求数 | `905,000 in 10s` | 💪 经过真实世界负载的实战测试 |
|
|
98
|
+
- **性能提升**: 相比基础版本提升 **25.7%**
|
|
99
|
+
- **内存优化**: 智能缓存和内存池管理
|
|
100
|
+
- **类型特化**: 针对特定数据类型的优化验证器
|
|
101
|
+
- **批量验证**: 支持数组数据的批量验证
|
|
111
102
|
|
|
112
|
-
|
|
103
|
+
```typescript
|
|
104
|
+
import {
|
|
105
|
+
validateAllSchemasExpanded,
|
|
106
|
+
createTypedValidator,
|
|
107
|
+
validateBatch
|
|
108
|
+
} from 'vafast/utils/validators/validators-ultra';
|
|
113
109
|
|
|
114
|
-
|
|
110
|
+
// 创建类型特化验证器
|
|
111
|
+
const userValidator = createTypedValidator(userSchema);
|
|
112
|
+
const validatedUser = userValidator(userData);
|
|
115
113
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
```ts
|
|
119
|
-
import { Server,json,setCookie,requireAuth } from "vafast";
|
|
120
|
-
import type { Route } from "vafast";
|
|
121
|
-
|
|
122
|
-
const routes: Route[] = [
|
|
123
|
-
{
|
|
124
|
-
method: "GET",
|
|
125
|
-
path: "/login",
|
|
126
|
-
handler: () => {
|
|
127
|
-
const headers = new Headers();
|
|
128
|
-
headers.append("Set-Cookie", setCookie("auth", "valid-token", {
|
|
129
|
-
httpOnly: true,
|
|
130
|
-
path: "/",
|
|
131
|
-
maxAge: 3600,
|
|
132
|
-
}));
|
|
133
|
-
return json({ message: "已登录" }, 200, headers);
|
|
134
|
-
},
|
|
135
|
-
middleware: [],
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
method: "GET",
|
|
139
|
-
path: "/private",
|
|
140
|
-
handler: () => json({ message: "仅限认证用户的秘密数据" }),
|
|
141
|
-
middleware: [requireAuth],
|
|
142
|
-
},
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
const server = new Server(routes);
|
|
146
|
-
|
|
147
|
-
export default {
|
|
148
|
-
fetch: (req: Request) => server.fetch(req),
|
|
149
|
-
};
|
|
114
|
+
// 批量验证
|
|
115
|
+
const validatedUsers = validateBatch(userSchema, userArray);
|
|
150
116
|
```
|
|
151
117
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
## 🔥 Vafast哲学 – 结构化简洁性的5大法则
|
|
155
|
-
|
|
156
|
-
后端应该是透明的、快速的,并且像架构一样设计 — 而不是像魔法。Vafast建立在五个现代原则之上:
|
|
118
|
+
## 📚 文档
|
|
157
119
|
|
|
158
|
-
|
|
159
|
-
|
|
120
|
+
- [📖 完整文档](./docs/)
|
|
121
|
+
- [🚀 快速开始](./docs/getting-started/quickstart.md)
|
|
122
|
+
- [🎯 核心功能](./docs/core/)
|
|
123
|
+
- [🔧 高级功能](./docs/advanced/)
|
|
124
|
+
- [📖 API参考](./docs/api/)
|
|
125
|
+
- [🧪 示例代码](./examples/)
|
|
160
126
|
|
|
161
|
-
|
|
162
|
-
异常携带类型、状态和可见性。您不捕获它们 — 您设计它们。
|
|
127
|
+
## 🧪 测试
|
|
163
128
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
129
|
+
```bash
|
|
130
|
+
# 运行所有测试
|
|
131
|
+
bun test
|
|
132
|
+
|
|
133
|
+
# 运行性能测试
|
|
134
|
+
bun run benchmark
|
|
135
|
+
|
|
136
|
+
# 运行特定测试
|
|
137
|
+
bun test:unit # 单元测试
|
|
138
|
+
bun test:integration # 集成测试
|
|
139
|
+
bun test:coverage # 覆盖率测试
|
|
140
|
+
|
|
141
|
+
# 运行基准测试
|
|
142
|
+
bun benchmark:quick # 快速测试
|
|
143
|
+
bun benchmark:validators # 验证器测试
|
|
144
|
+
bun benchmark:ultra # 超性能测试
|
|
145
|
+
bun benchmark:ultimate # 终极性能测试
|
|
146
|
+
bun benchmark:comprehensive # 综合测试
|
|
147
|
+
```
|
|
169
148
|
|
|
170
|
-
|
|
171
|
-
一个文件。无CLI。无隐藏魔法。您写的就是您部署的。
|
|
149
|
+
## 📊 性能基准
|
|
172
150
|
|
|
173
|
-
|
|
151
|
+
基于100,000次迭代的性能测试结果:
|
|
174
152
|
|
|
175
|
-
|
|
153
|
+
| 验证器 | 总耗时 | 性能提升 | 稳定性 |
|
|
154
|
+
|--------|--------|----------|---------|
|
|
155
|
+
| **Ultra标准版** | 24.28ms | 基准 | 稳定 |
|
|
156
|
+
| **Ultra展开版** | 23.63ms | **+2.7%** | 稳定 |
|
|
176
157
|
|
|
177
|
-
##
|
|
158
|
+
## 🤝 贡献
|
|
178
159
|
|
|
179
|
-
|
|
180
|
-
|-----------------|--------------------------------------------------|--------------------------------------------------|----------------------------------------------|
|
|
181
|
-
| **哲学** | 结构和副作用控制 | 简洁性和熟悉性 | 类型最大化和装饰器DSL |
|
|
182
|
-
| **路由** | 声明式`Route[]`结构 | 链式风格`app.get("/foo")` | 宏增强的处理器声明 |
|
|
183
|
-
| **中间件** | 显式`compose([...])`,每个路由作用域 | 全局`app.use()`和嵌套路由器 | 插件+生命周期钩子+装饰器 |
|
|
184
|
-
| **错误模型** | `VafastError`:带有元数据的结构化错误 | `throw`或`return c.text()` | `set.status()`,插件驱动处理 |
|
|
185
|
-
| **类型安全** | 类型驱动的配置和处理器(`Route<T>`) | 中等(上下文特定类型) | 极其强大,但与工具紧密耦合 |
|
|
186
|
-
| **响应API**| `json()`、`error()`作为纯返回值 | `c.json()`、`c.text()`方法 | `set.response()`副作用注入 |
|
|
187
|
-
| **可扩展性**| 中间件和组合原语 | 带有共享上下文的插件 | 插件+宏+装饰器 |
|
|
188
|
-
| **依赖项**| 🟢 零外部运行时依赖 | 🟡 轻量级 | 🔴 重量级:valibot、宏、SWC等 |
|
|
189
|
-
| **运行时支持** | ✅ Bun / Workers | ✅ Bun / Node / Workers/ Deno | ❌ 仅限Bun,限于SWC宏管道 |
|
|
190
|
-
| **理想用户** | API设计师、类型感知极简主义者、边缘开发者| 想要熟悉DX的Express/Deno用户 | 热爱宏和装饰器的TS高级用户 |
|
|
160
|
+
我们欢迎所有形式的贡献!请查看我们的 [贡献指南](./docs/contributing/) 开始参与。
|
|
191
161
|
|
|
192
|
-
|
|
162
|
+
### 快速开始
|
|
163
|
+
1. [Fork](https://github.com/vafast/vafast/fork) 项目
|
|
164
|
+
2. 创建功能分支 (`git checkout -b feature/amazing-feature`)
|
|
165
|
+
3. 提交更改 (`git commit -m 'feat: 添加新功能'`)
|
|
166
|
+
4. 推送到分支 (`git push origin feature/amazing-feature`)
|
|
167
|
+
5. 创建 [Pull Request](https://github.com/vafast/vafast/compare)
|
|
193
168
|
|
|
194
|
-
|
|
169
|
+
### 贡献类型
|
|
170
|
+
- 🐛 Bug 修复
|
|
171
|
+
- ✨ 新功能
|
|
172
|
+
- 📚 文档改进
|
|
173
|
+
- 🧪 测试用例
|
|
174
|
+
- 🚀 性能优化
|
|
195
175
|
|
|
196
|
-
|
|
176
|
+
### 社区
|
|
177
|
+
- [Issues](https://github.com/vafast/vafast/issues) - 报告 Bug 或请求功能
|
|
178
|
+
- [Discussions](https://github.com/vafast/vafast/discussions) - 讨论想法和问题
|
|
179
|
+
- [Releases](https://github.com/vafast/vafast/releases) - 查看最新版本
|
|
197
180
|
|
|
198
|
-
|
|
199
|
-
bun add vafast
|
|
200
|
-
```
|
|
181
|
+
## 📄 许可证
|
|
201
182
|
|
|
202
|
-
|
|
183
|
+
MIT License
|
|
203
184
|
|
|
204
|
-
|
|
205
|
-
npm install vafast
|
|
206
|
-
```
|
|
185
|
+
## 🏆 为什么选择Vafast?
|
|
207
186
|
|
|
208
|
-
|
|
187
|
+
1. **🚀 极致性能**: 超优化的验证器和路由系统
|
|
188
|
+
2. **🔒 开发体验**: 完整的TypeScript支持和智能提示
|
|
189
|
+
3. **✅ 生产就绪**: 经过严格测试的稳定版本
|
|
190
|
+
4. **⚡ 零配置**: 开箱即用的最佳实践配置
|
|
191
|
+
5. **🔄 活跃维护**: 持续的性能优化和功能更新
|
|
209
192
|
|
|
210
|
-
##
|
|
193
|
+
## 📊 性能基准
|
|
211
194
|
|
|
212
|
-
|
|
213
|
-
* ⚡️ 需要边缘速度API — 在Bun、Workers和Deno上亚毫秒响应时间。
|
|
195
|
+
基于100,000次迭代的性能测试结果:
|
|
214
196
|
|
|
215
|
-
|
|
197
|
+
| 验证器 | 总耗时 | 性能提升 | 稳定性 |
|
|
198
|
+
|--------|--------|----------|---------|
|
|
199
|
+
| **Ultra标准版** | 24.28ms | 基准 | 稳定 |
|
|
200
|
+
| **Ultra展开版** | 23.63ms | **+2.7%** | 稳定 |
|
|
216
201
|
|
|
217
|
-
|
|
202
|
+
## 🌟 特性亮点
|
|
218
203
|
|
|
219
|
-
|
|
204
|
+
- **⚡ 超高性能**: 基于优化的验证器和路由系统
|
|
205
|
+
- **🔒 类型安全**: 完整的TypeScript支持
|
|
206
|
+
- **🧩 中间件系统**: 灵活可扩展的中间件架构
|
|
207
|
+
- **✅ 内置验证**: 超优化的Schema验证器
|
|
208
|
+
- **🎯 零依赖**: 最小化外部依赖
|
|
209
|
+
- **🚀 Bun原生**: 专为Bun运行时优化
|
|
220
210
|
|
|
221
211
|
---
|
|
222
212
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
> 🚀 如果您厌倦了魔法、宏和单体 — 试试Vafast。
|
|
226
|
-
>
|
|
227
|
-
> 👉 **[⭐️ 在GitHub上加星标](https://github.com/vafast/vafast)** 加入这场运动。
|
|
228
|
-
|
|
229
|
-
[](https://github.com/vafast/vafast)
|
|
230
|
-
|
|
231
|
-
---
|
|
213
|
+
**Vafast** - 让Web开发更快、更安全、更高效! 🚀
|
|
232
214
|
|
|
233
|
-
##
|
|
215
|
+
## 📄 许可证
|
|
234
216
|
|
|
235
|
-
|
|
217
|
+
本项目采用 [MIT 许可证](./LICENSE)。
|
|
236
218
|
|
|
237
219
|
|
package/dist/auth/token.d.ts
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
export interface TokenPayload {
|
|
2
|
+
[key: string]: any;
|
|
3
|
+
exp?: number;
|
|
4
|
+
iat?: number;
|
|
5
|
+
sub?: string;
|
|
6
|
+
aud?: string;
|
|
7
|
+
iss?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TokenResult {
|
|
10
|
+
payload: TokenPayload;
|
|
11
|
+
token: string;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
}
|
|
14
|
+
export interface TokenOptions {
|
|
15
|
+
expiresIn?: number;
|
|
16
|
+
issuer?: string;
|
|
17
|
+
audience?: string;
|
|
18
|
+
subject?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class TokenError extends Error {
|
|
21
|
+
code: "INVALID_TOKEN" | "EXPIRED_TOKEN" | "INVALID_SIGNATURE" | "MALFORMED_TOKEN" | "INVALID_PAYLOAD";
|
|
22
|
+
constructor(message: string, code: "INVALID_TOKEN" | "EXPIRED_TOKEN" | "INVALID_SIGNATURE" | "MALFORMED_TOKEN" | "INVALID_PAYLOAD");
|
|
23
|
+
}
|
|
1
24
|
/** 生成令牌 */
|
|
2
|
-
export declare function generateToken(payload:
|
|
3
|
-
|
|
25
|
+
export declare function generateToken(payload: TokenPayload, secret: string, options?: TokenOptions): Promise<TokenResult>;
|
|
26
|
+
/** 验证令牌 */
|
|
27
|
+
export declare function verifyToken(token: string, secret: string): Promise<TokenPayload | null>;
|
|
28
|
+
/** 解析令牌(不验证签名) */
|
|
29
|
+
export declare function parseToken(token: string): TokenPayload | null;
|
|
30
|
+
/** 检查令牌是否过期 */
|
|
31
|
+
export declare function isTokenExpired(token: string): boolean;
|
|
32
|
+
/** 获取令牌剩余有效时间(秒) */
|
|
33
|
+
export declare function getTokenTimeRemaining(token: string): number;
|
|
34
|
+
/** 刷新令牌 */
|
|
35
|
+
export declare function refreshToken(token: string, secret: string, options?: TokenOptions): Promise<TokenResult | null>;
|
|
36
|
+
/** 创建访问令牌和刷新令牌对 */
|
|
37
|
+
export declare function createTokenPair(payload: TokenPayload, secret: string, options?: TokenOptions): Promise<{
|
|
38
|
+
accessToken: TokenResult;
|
|
39
|
+
refreshToken: TokenResult;
|
|
40
|
+
}>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// src/auth/token.ts
|
|
2
|
+
import { base64urlEncode, base64urlDecode } from "../utils/base64url";
|
|
3
|
+
export class TokenError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(message, code) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = "TokenError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
/** 使用 HMAC-SHA256 进行签名 */
|
|
13
|
+
async function sign(data, secret) {
|
|
14
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
15
|
+
const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
|
|
16
|
+
return btoa(String.fromCharCode.apply(null, Array.from(new Uint8Array(signature))));
|
|
17
|
+
}
|
|
18
|
+
/** 生成令牌 */
|
|
19
|
+
export async function generateToken(payload, secret, options = {}) {
|
|
20
|
+
const { expiresIn = 3600, issuer, audience, subject } = options;
|
|
21
|
+
// 创建令牌载荷,强制使用当前时间
|
|
22
|
+
const now = Math.floor(Date.now() / 1000);
|
|
23
|
+
const tokenPayload = {
|
|
24
|
+
...payload,
|
|
25
|
+
iat: now,
|
|
26
|
+
exp: now + expiresIn,
|
|
27
|
+
};
|
|
28
|
+
// 添加可选字段
|
|
29
|
+
if (issuer)
|
|
30
|
+
tokenPayload.iss = issuer;
|
|
31
|
+
if (audience)
|
|
32
|
+
tokenPayload.aud = audience;
|
|
33
|
+
if (subject)
|
|
34
|
+
tokenPayload.sub = subject;
|
|
35
|
+
const data = base64urlEncode(JSON.stringify(tokenPayload));
|
|
36
|
+
const sig = await sign(data, secret);
|
|
37
|
+
const token = `${data}.${base64urlEncode(sig)}`;
|
|
38
|
+
return {
|
|
39
|
+
payload: tokenPayload,
|
|
40
|
+
token,
|
|
41
|
+
expiresAt: tokenPayload.exp * 1000, // 转换为毫秒
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** 验证令牌 */
|
|
45
|
+
export async function verifyToken(token, secret) {
|
|
46
|
+
try {
|
|
47
|
+
const [data, sig] = token.split(".");
|
|
48
|
+
if (!data || !sig) {
|
|
49
|
+
throw new TokenError("令牌格式无效", "MALFORMED_TOKEN");
|
|
50
|
+
}
|
|
51
|
+
const expectedSig = await sign(data, secret);
|
|
52
|
+
const expected = base64urlEncode(expectedSig);
|
|
53
|
+
if (sig !== expected) {
|
|
54
|
+
throw new TokenError("令牌签名无效", "INVALID_SIGNATURE");
|
|
55
|
+
}
|
|
56
|
+
const payload = JSON.parse(base64urlDecode(data));
|
|
57
|
+
// 检查过期时间
|
|
58
|
+
if (payload.exp && Date.now() / 1000 > payload.exp) {
|
|
59
|
+
throw new TokenError("令牌已过期", "EXPIRED_TOKEN");
|
|
60
|
+
}
|
|
61
|
+
return payload;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
if (error instanceof TokenError) {
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
throw new TokenError("令牌验证失败", "INVALID_TOKEN");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** 解析令牌(不验证签名) */
|
|
71
|
+
export function parseToken(token) {
|
|
72
|
+
try {
|
|
73
|
+
const [data] = token.split(".");
|
|
74
|
+
if (!data)
|
|
75
|
+
return null;
|
|
76
|
+
return JSON.parse(base64urlDecode(data));
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** 检查令牌是否过期 */
|
|
83
|
+
export function isTokenExpired(token) {
|
|
84
|
+
const payload = parseToken(token);
|
|
85
|
+
if (!payload || !payload.exp)
|
|
86
|
+
return true;
|
|
87
|
+
return Date.now() / 1000 > payload.exp;
|
|
88
|
+
}
|
|
89
|
+
/** 获取令牌剩余有效时间(秒) */
|
|
90
|
+
export function getTokenTimeRemaining(token) {
|
|
91
|
+
const payload = parseToken(token);
|
|
92
|
+
if (!payload || !payload.exp)
|
|
93
|
+
return 0;
|
|
94
|
+
const remaining = payload.exp - Date.now() / 1000;
|
|
95
|
+
return Math.max(0, Math.floor(remaining));
|
|
96
|
+
}
|
|
97
|
+
/** 刷新令牌 */
|
|
98
|
+
export async function refreshToken(token, secret, options = {}) {
|
|
99
|
+
try {
|
|
100
|
+
const payload = await verifyToken(token, secret);
|
|
101
|
+
if (!payload)
|
|
102
|
+
return null;
|
|
103
|
+
// 移除时间相关字段,重新生成
|
|
104
|
+
const { exp, iat, ...cleanPayload } = payload;
|
|
105
|
+
// 添加延迟确保时间戳不同
|
|
106
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
107
|
+
return await generateToken(cleanPayload, secret, options);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** 创建访问令牌和刷新令牌对 */
|
|
114
|
+
export async function createTokenPair(payload, secret, options = {}) {
|
|
115
|
+
const accessToken = await generateToken(payload, secret, {
|
|
116
|
+
...options,
|
|
117
|
+
expiresIn: options.expiresIn || 3600, // 1小时
|
|
118
|
+
});
|
|
119
|
+
const refreshToken = await generateToken(payload, secret, {
|
|
120
|
+
...options,
|
|
121
|
+
expiresIn: 7 * 24 * 3600, // 7天
|
|
122
|
+
});
|
|
123
|
+
return { accessToken, refreshToken };
|
|
124
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
export * from "./server";
|
|
2
2
|
export * from "./middleware";
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./cookie";
|
|
3
|
+
export * from "./utils";
|
|
5
4
|
export * from "./router";
|
|
6
5
|
export * from "./middleware/authMiddleware";
|
|
7
6
|
export * from "./middleware/rateLimit";
|
|
8
7
|
export * from "./middleware/cors";
|
|
9
8
|
export * from "./auth/token";
|
|
10
9
|
export * from "./middleware/auth";
|
|
11
|
-
export * from "./utils/base64url";
|
|
12
10
|
export * from "./defineRoute";
|
|
13
|
-
export * from "./types";
|
|
11
|
+
export * from "./types/index";
|
|
12
|
+
export { Type } from "@sinclair/typebox";
|