befly 3.8.19 → 3.8.21

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 (78) hide show
  1. package/README.md +7 -6
  2. package/bunfig.toml +1 -1
  3. package/checks/checkApi.ts +92 -0
  4. package/checks/checkApp.ts +31 -0
  5. package/{check.ts → checks/checkTable.ts} +28 -159
  6. package/config.ts +71 -0
  7. package/hooks/auth.ts +30 -0
  8. package/hooks/cors.ts +48 -0
  9. package/hooks/errorHandler.ts +23 -0
  10. package/hooks/parser.ts +67 -0
  11. package/hooks/permission.ts +54 -0
  12. package/hooks/rateLimit.ts +70 -0
  13. package/hooks/requestId.ts +24 -0
  14. package/hooks/requestLogger.ts +25 -0
  15. package/hooks/responseFormatter.ts +64 -0
  16. package/hooks/validator.ts +34 -0
  17. package/lib/database.ts +28 -25
  18. package/lib/dbHelper.ts +3 -3
  19. package/lib/jwt.ts +90 -99
  20. package/lib/logger.ts +44 -23
  21. package/lib/redisHelper.ts +19 -22
  22. package/loader/loadApis.ts +69 -114
  23. package/loader/loadHooks.ts +65 -0
  24. package/loader/loadPlugins.ts +50 -219
  25. package/main.ts +106 -133
  26. package/package.json +23 -14
  27. package/paths.ts +20 -0
  28. package/plugins/cache.ts +1 -3
  29. package/plugins/db.ts +8 -11
  30. package/plugins/logger.ts +5 -3
  31. package/plugins/redis.ts +10 -14
  32. package/router/api.ts +60 -106
  33. package/router/root.ts +15 -12
  34. package/router/static.ts +54 -58
  35. package/sync/syncAll.ts +58 -0
  36. package/sync/syncApi.ts +264 -0
  37. package/sync/syncDb/apply.ts +194 -0
  38. package/sync/syncDb/constants.ts +76 -0
  39. package/sync/syncDb/ddl.ts +194 -0
  40. package/sync/syncDb/helpers.ts +200 -0
  41. package/sync/syncDb/index.ts +164 -0
  42. package/sync/syncDb/schema.ts +201 -0
  43. package/sync/syncDb/sqlite.ts +50 -0
  44. package/sync/syncDb/table.ts +321 -0
  45. package/sync/syncDb/tableCreate.ts +146 -0
  46. package/sync/syncDb/version.ts +72 -0
  47. package/sync/syncDb.ts +19 -0
  48. package/sync/syncDev.ts +206 -0
  49. package/sync/syncMenu.ts +331 -0
  50. package/tests/cipher.test.ts +248 -0
  51. package/tests/dbHelper-advanced.test.ts +717 -0
  52. package/tests/dbHelper-columns.test.ts +266 -0
  53. package/tests/dbHelper-execute.test.ts +240 -0
  54. package/tests/fields-redis-cache.test.ts +123 -0
  55. package/tests/fields-validate.test.ts +99 -0
  56. package/tests/integration.test.ts +202 -0
  57. package/tests/jwt.test.ts +122 -0
  58. package/tests/logger.test.ts +94 -0
  59. package/tests/redisHelper.test.ts +231 -0
  60. package/tests/sqlBuilder-advanced.test.ts +593 -0
  61. package/tests/sqlBuilder.test.ts +184 -0
  62. package/tests/util.test.ts +95 -0
  63. package/tests/validator-advanced.test.ts +653 -0
  64. package/tests/validator.test.ts +148 -0
  65. package/tests/xml.test.ts +101 -0
  66. package/tsconfig.json +2 -4
  67. package/types/api.d.ts +6 -0
  68. package/types/befly.d.ts +152 -28
  69. package/types/context.d.ts +29 -3
  70. package/types/hook.d.ts +35 -0
  71. package/types/index.ts +14 -1
  72. package/types/plugin.d.ts +6 -7
  73. package/types/sync.d.ts +403 -0
  74. package/env.ts +0 -106
  75. package/lib/middleware.ts +0 -275
  76. package/types/env.ts +0 -65
  77. package/types/util.d.ts +0 -45
  78. package/util.ts +0 -257
@@ -0,0 +1,148 @@
1
+ import { describe, test, expect } from 'bun:test';
2
+ import { Validator } from '../lib/validator';
3
+
4
+ const validator = new Validator();
5
+
6
+ describe('Validator - 基本验证', () => {
7
+ test('验证通过', () => {
8
+ const data = { username: 'john' };
9
+ const rules = { username: { name: '用户名', type: 'string', min: 2, max: 20 } };
10
+ const result = validator.validate(data, rules);
11
+ expect(result.code).toBe(0);
12
+ expect(Object.keys(result.fields).length).toBe(0);
13
+ });
14
+
15
+ test('验证失败 - 必填字段缺失', () => {
16
+ const data = {};
17
+ const rules = { username: { name: '用户名', type: 'string', min: 2, max: 20 } };
18
+ const required = ['username'];
19
+ const result = validator.validate(data, rules, required);
20
+ expect(result.code).toBe(1);
21
+ expect(result.fields.username).toContain('必填项');
22
+ });
23
+
24
+ test('验证失败 - 字段值为空', () => {
25
+ const data = { username: '' };
26
+ const rules = { username: { name: '用户名', type: 'string', min: 2, max: 20 } };
27
+ const required = ['username'];
28
+ const result = validator.validate(data, rules, required);
29
+ expect(result.code).toBe(1);
30
+ expect(result.fields.username).toBeDefined();
31
+ });
32
+ });
33
+
34
+ describe('Validator - 类型验证', () => {
35
+ test('string 类型', () => {
36
+ const data = { name: 'test' };
37
+ const rules = { name: { name: '名称', type: 'string', min: 2, max: 10 } };
38
+ const result = validator.validate(data, rules);
39
+ expect(result.code).toBe(0);
40
+ });
41
+
42
+ test('number 类型', () => {
43
+ const data = { age: 25 };
44
+ const rules = { age: { name: '年龄', type: 'number', min: 0, max: 150 } };
45
+ const result = validator.validate(data, rules);
46
+ expect(result.code).toBe(0);
47
+ });
48
+
49
+ test('email 验证', () => {
50
+ const data = { email: 'test@example.com' };
51
+ const rules = { email: { name: '邮箱', type: 'string', regexp: '@email' } };
52
+ const result = validator.validate(data, rules);
53
+ expect(result.code).toBe(0);
54
+ });
55
+
56
+ test('phone 验证', () => {
57
+ const data = { phone: '13800138000' };
58
+ const rules = { phone: { name: '手机号', type: 'string', regexp: '@phone' } };
59
+ const result = validator.validate(data, rules);
60
+ expect(result.code).toBe(0);
61
+ });
62
+ });
63
+
64
+ describe('Validator - 长度验证', () => {
65
+ test('string 最小长度', () => {
66
+ const data = { name: 'a' };
67
+ const rules = { name: { name: '名称', type: 'string', min: 2, max: 10 } };
68
+ const result = validator.validate(data, rules);
69
+ expect(result.code).toBe(1);
70
+ expect(result.fields.name).toBeDefined();
71
+ });
72
+
73
+ test('string 最大长度', () => {
74
+ const data = { name: 'a'.repeat(20) };
75
+ const rules = { name: { name: '名称', type: 'string', min: 2, max: 10 } };
76
+ const result = validator.validate(data, rules);
77
+ expect(result.code).toBe(1);
78
+ expect(result.fields.name).toBeDefined();
79
+ });
80
+
81
+ test('number 范围验证', () => {
82
+ const data = { age: 200 };
83
+ const rules = { age: { name: '年龄', type: 'number', min: 0, max: 150 } };
84
+ const result = validator.validate(data, rules);
85
+ expect(result.code).toBe(1);
86
+ expect(result.fields.age).toBeDefined();
87
+ });
88
+ });
89
+
90
+ describe('Validator - 正则验证', () => {
91
+ test('正则别名 @email - 有效邮箱', () => {
92
+ const data = { email: 'test@example.com' };
93
+ const rules = { email: { name: '邮箱', type: 'string', regexp: '@email' } };
94
+ const result = validator.validate(data, rules);
95
+ expect(result.code).toBe(0);
96
+ });
97
+
98
+ test('正则别名 @email - 无效邮箱', () => {
99
+ const data = { email: 'invalid-email' };
100
+ const rules = { email: { name: '邮箱', type: 'string', regexp: '@email' } };
101
+ const result = validator.validate(data, rules);
102
+ expect(result.code).toBe(1);
103
+ expect(result.fields.email).toBeDefined();
104
+ });
105
+
106
+ test('正则别名 @phone - 有效手机号', () => {
107
+ const data = { phone: '13800138000' };
108
+ const rules = { phone: { name: '手机号', type: 'string', regexp: '@phone' } };
109
+ const result = validator.validate(data, rules);
110
+ expect(result.code).toBe(0);
111
+ });
112
+
113
+ test('正则别名 @phone - 无效手机号', () => {
114
+ const data = { phone: '12345' };
115
+ const rules = { phone: { name: '手机号', type: 'string', regexp: '@phone' } };
116
+ const result = validator.validate(data, rules);
117
+ expect(result.code).toBe(1);
118
+ expect(result.fields.phone).toBeDefined();
119
+ });
120
+
121
+ test('自定义正则 - 纯数字', () => {
122
+ const data = { code: '12a' };
123
+ const rules = { code: { name: '验证码', type: 'string', regexp: '^\\d+$' } };
124
+ const result = validator.validate(data, rules);
125
+ expect(result.code).toBe(1);
126
+ expect(result.fields.code).toBeDefined();
127
+ });
128
+ });
129
+
130
+ describe('Validator - 参数检查', () => {
131
+ test('data 不是对象', () => {
132
+ const result = validator.validate(null as any, {});
133
+ expect(result.code).toBe(1);
134
+ expect(result.fields.error).toContain('对象格式');
135
+ });
136
+
137
+ test('rules 不是对象', () => {
138
+ const result = validator.validate({}, null as any);
139
+ expect(result.code).toBe(1);
140
+ expect(result.fields.error).toContain('对象格式');
141
+ });
142
+
143
+ test('required 不是数组', () => {
144
+ const result = validator.validate({}, {}, 'invalid' as any);
145
+ expect(result.code).toBe(1);
146
+ expect(result.fields.error).toContain('数组格式');
147
+ });
148
+ });
@@ -0,0 +1,101 @@
1
+ import { describe, test, expect } from 'bun:test';
2
+ import { Xml } from '../lib/xml';
3
+
4
+ describe('Xml - 基本解析', () => {
5
+ test('解析简单元素', () => {
6
+ const xml = new Xml();
7
+ const result = xml.parse('<root>Hello</root>');
8
+ expect(result).toBe('Hello');
9
+ });
10
+
11
+ test('解析嵌套元素', () => {
12
+ const xml = new Xml();
13
+ const result = xml.parse('<root><child>Value</child></root>');
14
+ expect(result).toEqual({ child: 'Value' });
15
+ });
16
+
17
+ test('解析多个同名元素', () => {
18
+ const xml = new Xml();
19
+ const result = xml.parse('<root><item>A</item><item>B</item></root>');
20
+ expect(result).toEqual({ item: ['A', 'B'] });
21
+ });
22
+
23
+ test('解析空元素', () => {
24
+ const xml = new Xml();
25
+ const result = xml.parse('<root></root>');
26
+ expect(result).toBe('');
27
+ });
28
+
29
+ test('解析自闭合标签', () => {
30
+ const xml = new Xml();
31
+ const result = xml.parse('<root><item/></root>');
32
+ expect(result).toEqual({ item: '' });
33
+ });
34
+ });
35
+
36
+ describe('Xml - 属性解析', () => {
37
+ test('解析元素属性', () => {
38
+ const xml = new Xml();
39
+ const result = xml.parse('<root id="1">Value</root>') as any;
40
+ expect(result['@id']).toBe('1');
41
+ expect(result['#text']).toBe('Value');
42
+ });
43
+
44
+ test('解析多个属性', () => {
45
+ const xml = new Xml();
46
+ const result = xml.parse('<user id="123" name="John">Content</user>') as any;
47
+ expect(result['@id']).toBe('123');
48
+ expect(result['@name']).toBe('John');
49
+ expect(result['#text']).toBe('Content');
50
+ });
51
+
52
+ test('忽略属性', () => {
53
+ const xml = new Xml({ ignoreAttributes: true });
54
+ const result = xml.parse('<root id="1">Value</root>');
55
+ expect(result).toBe('Value');
56
+ });
57
+ });
58
+
59
+ describe('Xml - 数值解析', () => {
60
+ test('自动解析数字', () => {
61
+ const xml = new Xml();
62
+ const result = xml.parse('<root>123</root>');
63
+ expect(result).toBe(123);
64
+ });
65
+
66
+ test('自动解析布尔值', () => {
67
+ const xml = new Xml();
68
+ const result1 = xml.parse('<root>true</root>');
69
+ const result2 = xml.parse('<root>false</root>');
70
+ expect(result1).toBe(true);
71
+ expect(result2).toBe(false);
72
+ });
73
+
74
+ test('禁用数字解析', () => {
75
+ const xml = new Xml({ parseNumbers: false });
76
+ const result = xml.parse('<root>123</root>');
77
+ expect(result).toBe('123');
78
+ });
79
+ });
80
+
81
+ describe('Xml - 错误处理', () => {
82
+ test('拒绝非字符串输入', () => {
83
+ const xml = new Xml();
84
+ expect(() => xml.parse(123 as any)).toThrow('无效的 XML 数据');
85
+ });
86
+
87
+ test('拒绝空字符串', () => {
88
+ const xml = new Xml();
89
+ expect(() => xml.parse('')).toThrow('非空字符串');
90
+ });
91
+
92
+ test('拒绝只有空格的字符串', () => {
93
+ const xml = new Xml();
94
+ expect(() => xml.parse(' ')).toThrow('非空字符串');
95
+ });
96
+
97
+ test('检测未闭合标签', () => {
98
+ const xml = new Xml();
99
+ expect(() => xml.parse('<root><item>')).toThrow('未找到结束标签');
100
+ });
101
+ });
package/tsconfig.json CHANGED
@@ -33,9 +33,7 @@
33
33
  "isolatedModules": true,
34
34
 
35
35
  // 输出
36
- "declaration": true,
37
- "declarationMap": true,
38
- "sourceMap": true,
36
+ "noEmit": true,
39
37
  "removeComments": false,
40
38
  "importHelpers": false,
41
39
 
@@ -45,7 +43,7 @@
45
43
  "checkJs": false,
46
44
 
47
45
  // Bun 特定
48
- "types": ["bun-types"],
46
+ "types": ["bun"],
49
47
 
50
48
  // 路径
51
49
  "baseUrl": ".",
package/types/api.d.ts CHANGED
@@ -84,6 +84,12 @@ export interface ApiRoute<T = any, R = any> {
84
84
  /** 必填字段(可选,默认 []) */
85
85
  required?: string[];
86
86
 
87
+ /** 缓存配置(可选,单位:秒) */
88
+ cache?: number;
89
+
90
+ /** 限流配置(可选,格式:次数/秒,如 "10/60" 表示 60秒内10次) */
91
+ rateLimit?: string;
92
+
87
93
  /** 路由路径(运行时生成) */
88
94
  route?: string;
89
95
  }
package/types/befly.d.ts CHANGED
@@ -12,46 +12,170 @@ import type { Database } from 'bun:sqlite';
12
12
  import type { DbHelper } from '../lib/dbHelper.js';
13
13
  import type { RedisHelper } from '../lib/redisHelper.js';
14
14
  import type { Cipher } from '../lib/cipher.js';
15
+ import type { CacheHelper } from '../lib/cacheHelper.js';
15
16
 
16
17
  /**
17
- * Befly 应用选项
18
+ * 日志配置
18
19
  */
19
- export interface BeflyOptions {
20
- /** 应用名称 */
21
- name?: string;
20
+ export interface LoggerConfig {
21
+ /** 是否开启调试模式 (0: 关闭, 1: 开启) @default 1 */
22
+ debug?: number;
23
+ /** 日志排除字段 (逗号分隔) @default 'password,token,secret' */
24
+ excludeFields?: string;
25
+ /** 日志目录 @default './logs' */
26
+ dir?: string;
27
+ /** 是否输出到控制台 (0: 关闭, 1: 开启) @default 1 */
28
+ console?: number;
29
+ /** 单个日志文件最大大小 (字节) @default 10485760 (10MB) */
30
+ maxSize?: number;
31
+ }
22
32
 
23
- /** 监听主机 */
33
+ /**
34
+ * 数据库配置
35
+ */
36
+ export interface DatabaseConfig {
37
+ /** 是否启用数据库 (0: 关闭, 1: 开启) @default 0 */
38
+ enable?: number;
39
+ /** 数据库类型 ('mysql' | 'postgres' | 'sqlite') @default 'sqlite' */
40
+ type?: string;
41
+ /** 数据库主机 @default '127.0.0.1' */
24
42
  host?: string;
25
-
26
- /** 监听端口 */
43
+ /** 数据库端口 @default 3306 */
27
44
  port?: number;
45
+ /** 数据库用户名 @default 'root' */
46
+ username?: string;
47
+ /** 数据库密码 @default '' */
48
+ password?: string;
49
+ /** 数据库名称 @default 'befly' */
50
+ database?: string;
51
+ /** 连接池最大连接数 @default 1 */
52
+ poolMax?: number;
53
+ }
28
54
 
29
- /** 是否启用 CORS */
30
- cors?: boolean | CorsOptions;
31
-
32
- /** 静态文件目录 */
33
- staticDir?: string;
55
+ /**
56
+ * Redis 配置
57
+ */
58
+ export interface RedisConfig {
59
+ /** Redis 主机 @default '127.0.0.1' */
60
+ host?: string;
61
+ /** Redis 端口 @default 6379 */
62
+ port?: number;
63
+ /** Redis 用户名 @default '' */
64
+ username?: string;
65
+ /** Redis 密码 @default '' */
66
+ password?: string;
67
+ /** Redis 数据库索引 @default 0 */
68
+ db?: number;
69
+ /** Redis Key 前缀 @default 'befly:' */
70
+ prefix?: string;
71
+ }
34
72
 
35
- /** 上传文件目录 */
36
- uploadDir?: string;
73
+ /**
74
+ * JWT 配置
75
+ */
76
+ export interface AuthConfig {
77
+ /** JWT 密钥 @default 'befly-secret' */
78
+ secret?: string;
79
+ /** 过期时间 @default '7d' */
80
+ expiresIn?: string | number;
81
+ /** 签名算法 @default 'HS256' */
82
+ algorithm?: string;
83
+ }
37
84
 
38
- /** 最大请求体大小 */
39
- maxBodySize?: number;
85
+ /**
86
+ * CORS 配置
87
+ */
88
+ export interface CorsConfig {
89
+ /** 允许的来源 @default '*' */
90
+ origin?: string;
91
+ /** 允许的方法 @default 'GET,HEAD,PUT,PATCH,POST,DELETE' */
92
+ methods?: string;
93
+ /** 允许的头 @default 'Content-Type,Authorization' */
94
+ allowedHeaders?: string;
95
+ /** 暴露的头 @default '' */
96
+ exposedHeaders?: string;
97
+ /** 预检请求缓存时间 (秒) @default 86400 */
98
+ maxAge?: number;
99
+ /** 是否允许凭证 @default 'true' */
100
+ credentials?: string;
101
+ }
40
102
 
41
- /** 自定义配置 */
103
+ /**
104
+ * Befly 构造函数选项(最多 2 级结构)
105
+ */
106
+ export interface BeflyOptions {
107
+ // ========== 核心参数 ==========
108
+ /** 运行环境 ('development' | 'production') @default 'development' */
109
+ nodeEnv?: string;
110
+ /** 应用名称 @default 'Befly App' */
111
+ appName?: string;
112
+ /** 应用端口 @default 3000 */
113
+ appPort?: number;
114
+ /** 应用主机 @default '0.0.0.0' */
115
+ appHost?: string;
116
+ /** 开发者邮箱 (用于 syncDev) @default 'dev@qq.com' */
117
+ devEmail?: string;
118
+ /** 开发者密码 (用于 syncDev) */
119
+ devPassword?: string;
120
+ /** 请求体大小限制 (字节) @default 1048576 (1MB) */
121
+ bodyLimit?: number;
122
+ /** 时区 @default 'Asia/Shanghai' */
123
+ tz?: string;
124
+
125
+ // ========== 插件配置 ==========
126
+ /** 日志插件配置 */
127
+ logger?: LoggerConfig;
128
+ /** 数据库插件配置 */
129
+ db?: DatabaseConfig;
130
+ /** Redis 插件配置 */
131
+ redis?: RedisConfig;
132
+ /** 认证插件配置 */
133
+ auth?: AuthConfig;
134
+ /** CORS 插件配置 */
135
+ cors?: CorsConfig;
136
+ /** 禁用的钩子列表 */
137
+ disableHooks?: string[];
138
+ /** 禁用的插件列表 */
139
+ disablePlugins?: string[];
140
+ /** 其他插件配置 */
42
141
  [key: string]: any;
43
142
  }
44
143
 
45
144
  /**
46
- * CORS 配置选项
47
- */
48
- export interface CorsOptions {
49
- origin?: string | string[] | boolean;
50
- methods?: string[];
51
- allowedHeaders?: string[];
52
- exposedHeaders?: string[];
53
- credentials?: boolean;
54
- maxAge?: number;
145
+ * Befly 应用上下文
146
+ * 包含所有插件挂载的实例
147
+ */
148
+ export interface BeflyContext extends KeyValue {
149
+ // ========== 核心插件(带下划线前缀) ==========
150
+ /** 数据库助手 (db 插件) */
151
+ _db?: DbHelper;
152
+
153
+ /** Redis 助手 (redis 插件) */
154
+ _redis?: RedisHelper;
155
+
156
+ /** 日志器 (logger 插件) */
157
+ _logger?: typeof Logger;
158
+
159
+ /** 缓存助手 (cache 插件) */
160
+ _cache?: CacheHelper;
161
+
162
+ // ========== 核心插件便捷访问(无前缀) ==========
163
+ /** 数据库助手便捷访问 */
164
+ db?: DbHelper;
165
+
166
+ /** Redis 助手便捷访问 */
167
+ redis?: RedisHelper;
168
+
169
+ /** 日志器便捷访问 */
170
+ logger?: typeof Logger;
171
+
172
+ /** 缓存助手便捷访问 */
173
+ cache?: CacheHelper;
174
+
175
+ // ========== 动态插件 ==========
176
+ /** 组件插件:addon_{addonName}_{pluginName} */
177
+ /** 项目插件:app_{pluginName} */
178
+ [key: string]: any;
55
179
  }
56
180
 
57
181
  /**
@@ -122,9 +246,9 @@ export interface Befly {
122
246
  handleRequest(request: Request): Promise<Response>;
123
247
 
124
248
  /**
125
- * 注册中间件
249
+ * 注册钩子
126
250
  */
127
- use(middleware: Function): void;
251
+ use(hook: Function): void;
128
252
 
129
253
  /**
130
254
  * 获取配置
@@ -1,7 +1,33 @@
1
1
  /**
2
2
  * 请求上下文类型定义
3
- * 实现代码位于 util.ts,类型定义位于 types/util.d.ts
4
3
  */
5
4
 
6
- // 重新导出 RequestContext 接口
7
- export type { RequestContext } from './util.js';
5
+ import type { ApiRoute } from './api.js';
6
+
7
+ /**
8
+ * 请求上下文接口
9
+ */
10
+ export interface RequestContext {
11
+ /** 请求体参数 */
12
+ body: Record<string, any>;
13
+ /** 用户信息 */
14
+ user: Record<string, any>;
15
+ /** 原始请求对象 */
16
+ req: Request;
17
+ /** 请求开始时间(毫秒) */
18
+ now: number;
19
+ /** 客户端 IP 地址 */
20
+ ip?: string;
21
+ /** API 路由路径(如 POST/api/user/login) */
22
+ route?: string;
23
+ /** 当前请求的 API 路由对象 */
24
+ api?: ApiRoute;
25
+ /** 响应对象(如果设置了此属性,将直接返回该响应) */
26
+ response?: Response;
27
+ /** 原始处理结果(未转换为 Response 对象前) */
28
+ result?: any;
29
+ /** 请求唯一 ID */
30
+ requestId?: string;
31
+ /** CORS 响应头 */
32
+ corsHeaders?: Record<string, string>;
33
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Befly 钩子系统类型定义
3
+ */
4
+
5
+ import type { BeflyContext } from './befly.js';
6
+ import type { RequestContext } from './context.js';
7
+
8
+ /**
9
+ * 钩子处理函数类型
10
+ */
11
+ export type Next = () => Promise<void>;
12
+ export type HookHandler = (befly: BeflyContext, ctx: RequestContext, next: Next) => Promise<void> | void;
13
+
14
+ /**
15
+ * 钩子配置类型
16
+ */
17
+ export interface Hook {
18
+ /** 钩子名称(运行时动态添加,由文件名生成) */
19
+ name?: string;
20
+
21
+ /** 依赖的钩子列表(在这些钩子之后执行) */
22
+ after?: string[];
23
+
24
+ /** 执行顺序(数字越小越先执行,同级别时使用) */
25
+ order?: number;
26
+
27
+ /** 钩子处理函数 */
28
+ handler: HookHandler;
29
+
30
+ /** 钩子配置 */
31
+ config?: Record<string, any>;
32
+
33
+ /** 钩子描述 */
34
+ description?: string;
35
+ }
package/types/index.ts CHANGED
@@ -2,4 +2,17 @@
2
2
  * 类型定义导出
3
3
  */
4
4
 
5
- export * from './env.js';
5
+ export * from './addon.js';
6
+ export * from './api.js';
7
+ export * from './befly.js';
8
+ export * from './common.js';
9
+ export * from './context.js';
10
+ export * from './crypto.js';
11
+ export * from './database.js';
12
+ export * from './jwt.js';
13
+ export * from './logger.js';
14
+ export * from './plugin.js';
15
+ export * from './redis.js';
16
+ export * from './tool.js';
17
+ export * from './validator.js';
18
+ export * from './sync.js';
package/types/plugin.d.ts CHANGED
@@ -13,16 +13,15 @@ export type PluginInitFunction = (befly: BeflyContext) => Promise<any> | any;
13
13
  /**
14
14
  * 插件请求处理钩子函数类型
15
15
  */
16
- export type PluginGetHook = (befly: BeflyContext, ctx: RequestContext, req: Request) => Promise<void> | void;
16
+ export type Next = () => Promise<void>;
17
17
 
18
18
  /**
19
19
  * 插件配置类型
20
20
  */
21
21
  export interface Plugin {
22
- /** 插件名称 */
23
- name: string;
24
-
25
- /** 插件名称(运行时动态添加,与 name 相同) */
22
+ /** 插件名称(运行时动态添加,由文件名生成) */
23
+ name?: string;
24
+ /** @deprecated use name instead */
26
25
  pluginName?: string;
27
26
 
28
27
  /** 依赖的插件列表(在这些插件之后执行) */
@@ -31,8 +30,8 @@ export interface Plugin {
31
30
  /** 插件初始化函数 */
32
31
  onInit?: PluginInitFunction;
33
32
 
34
- /** 请求处理钩子(在每个 API 请求时执行) */
35
- onGet?: PluginGetHook;
33
+ /** 插件配置 */
34
+ config?: Record<string, any>;
36
35
 
37
36
  /** 插件描述 */
38
37
  description?: string;