befly 3.10.18 → 3.10.19

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 (220) hide show
  1. package/README.md +83 -307
  2. package/dist/befly.config.d.ts +7 -0
  3. package/{befly.config.ts → dist/befly.config.js} +10 -33
  4. package/dist/checks/checkApi.d.ts +1 -0
  5. package/{checks/checkApi.ts → dist/checks/checkApi.js} +11 -28
  6. package/dist/checks/checkHook.d.ts +1 -0
  7. package/{checks/checkHook.ts → dist/checks/checkHook.js} +11 -20
  8. package/dist/checks/checkMenu.d.ts +7 -0
  9. package/{checks/checkMenu.ts → dist/checks/checkMenu.js} +18 -53
  10. package/dist/checks/checkPlugin.d.ts +1 -0
  11. package/{checks/checkPlugin.ts → dist/checks/checkPlugin.js} +11 -20
  12. package/dist/checks/checkTable.d.ts +6 -0
  13. package/{checks/checkTable.ts → dist/checks/checkTable.js} +17 -41
  14. package/dist/configs/presetFields.d.ts +4 -0
  15. package/{configs/presetFields.ts → dist/configs/presetFields.js} +1 -1
  16. package/dist/configs/presetRegexp.d.ts +145 -0
  17. package/{utils/regex.ts → dist/configs/presetRegexp.js} +8 -31
  18. package/dist/hooks/auth.d.ts +5 -0
  19. package/{hooks/auth.ts → dist/hooks/auth.js} +6 -10
  20. package/dist/hooks/cors.d.ts +9 -0
  21. package/{hooks/cors.ts → dist/hooks/cors.js} +3 -13
  22. package/dist/hooks/parser.d.ts +12 -0
  23. package/{hooks/parser.ts → dist/hooks/parser.js} +29 -44
  24. package/dist/hooks/permission.d.ts +12 -0
  25. package/{hooks/permission.ts → dist/hooks/permission.js} +14 -25
  26. package/dist/hooks/validator.d.ts +9 -0
  27. package/{hooks/validator.ts → dist/hooks/validator.js} +7 -14
  28. package/dist/lib/asyncContext.d.ts +21 -0
  29. package/dist/lib/asyncContext.js +27 -0
  30. package/dist/lib/cacheHelper.d.ts +95 -0
  31. package/{lib/cacheHelper.ts → dist/lib/cacheHelper.js} +45 -105
  32. package/dist/lib/cacheKeys.d.ts +23 -0
  33. package/{lib/cacheKeys.ts → dist/lib/cacheKeys.js} +5 -10
  34. package/dist/lib/cipher.d.ts +153 -0
  35. package/{lib/cipher.ts → dist/lib/cipher.js} +23 -44
  36. package/dist/lib/connect.d.ts +91 -0
  37. package/{lib/connect.ts → dist/lib/connect.js} +47 -88
  38. package/dist/lib/dbDialect.d.ts +87 -0
  39. package/{lib/dbDialect.ts → dist/lib/dbDialect.js} +32 -112
  40. package/dist/lib/dbHelper.d.ts +204 -0
  41. package/{lib/dbHelper.ts → dist/lib/dbHelper.js} +83 -240
  42. package/dist/lib/dbUtils.d.ts +68 -0
  43. package/{lib/dbUtils.ts → dist/lib/dbUtils.js} +51 -125
  44. package/dist/lib/jwt.d.ts +13 -0
  45. package/{lib/jwt.ts → dist/lib/jwt.js} +11 -32
  46. package/dist/lib/logger.d.ts +32 -0
  47. package/{lib/logger.ts → dist/lib/logger.js} +202 -279
  48. package/dist/lib/redisHelper.d.ts +185 -0
  49. package/{lib/redisHelper.ts → dist/lib/redisHelper.js} +97 -141
  50. package/dist/lib/sqlBuilder.d.ts +160 -0
  51. package/{lib/sqlBuilder.ts → dist/lib/sqlBuilder.js} +132 -278
  52. package/dist/lib/sqlCheck.d.ts +23 -0
  53. package/{lib/sqlCheck.ts → dist/lib/sqlCheck.js} +24 -41
  54. package/dist/lib/validator.d.ts +45 -0
  55. package/{lib/validator.ts → dist/lib/validator.js} +44 -61
  56. package/dist/loader/loadApis.d.ts +12 -0
  57. package/{loader/loadApis.ts → dist/loader/loadApis.js} +9 -19
  58. package/dist/loader/loadHooks.d.ts +8 -0
  59. package/{loader/loadHooks.ts → dist/loader/loadHooks.js} +7 -21
  60. package/dist/loader/loadPlugins.d.ts +8 -0
  61. package/{loader/loadPlugins.ts → dist/loader/loadPlugins.js} +10 -22
  62. package/dist/main.d.ts +26 -0
  63. package/{main.ts → dist/main.js} +60 -99
  64. package/dist/paths.d.ts +93 -0
  65. package/{paths.ts → dist/paths.js} +6 -19
  66. package/dist/plugins/cache.d.ts +14 -0
  67. package/{plugins/cache.ts → dist/plugins/cache.js} +5 -12
  68. package/dist/plugins/cipher.d.ts +10 -0
  69. package/{plugins/cipher.ts → dist/plugins/cipher.js} +2 -6
  70. package/dist/plugins/config.d.ts +10 -0
  71. package/dist/plugins/config.js +6 -0
  72. package/dist/plugins/db.d.ts +14 -0
  73. package/{plugins/db.ts → dist/plugins/db.js} +9 -17
  74. package/dist/plugins/jwt.d.ts +10 -0
  75. package/dist/plugins/jwt.js +10 -0
  76. package/dist/plugins/logger.d.ts +28 -0
  77. package/{plugins/logger.ts → dist/plugins/logger.js} +3 -8
  78. package/dist/plugins/redis.d.ts +14 -0
  79. package/{plugins/redis.ts → dist/plugins/redis.js} +7 -12
  80. package/dist/plugins/tool.d.ts +79 -0
  81. package/{plugins/tool.ts → dist/plugins/tool.js} +7 -30
  82. package/dist/router/api.d.ts +14 -0
  83. package/dist/router/api.js +107 -0
  84. package/dist/router/static.d.ts +9 -0
  85. package/{router/static.ts → dist/router/static.js} +20 -34
  86. package/dist/scripts/ensureDist.d.ts +1 -0
  87. package/dist/scripts/ensureDist.js +80 -0
  88. package/dist/sync/syncApi.d.ts +3 -0
  89. package/{sync/syncApi.ts → dist/sync/syncApi.js} +34 -54
  90. package/dist/sync/syncCache.d.ts +2 -0
  91. package/{sync/syncCache.ts → dist/sync/syncCache.js} +1 -6
  92. package/dist/sync/syncDev.d.ts +6 -0
  93. package/{sync/syncDev.ts → dist/sync/syncDev.js} +29 -62
  94. package/dist/sync/syncMenu.d.ts +14 -0
  95. package/{sync/syncMenu.ts → dist/sync/syncMenu.js} +65 -125
  96. package/dist/sync/syncTable.d.ts +151 -0
  97. package/{sync/syncTable.ts → dist/sync/syncTable.js} +171 -378
  98. package/{types → dist/types}/api.d.ts +8 -47
  99. package/dist/types/api.js +4 -0
  100. package/{types → dist/types}/befly.d.ts +31 -222
  101. package/dist/types/befly.js +4 -0
  102. package/{types → dist/types}/cache.d.ts +7 -15
  103. package/dist/types/cache.js +4 -0
  104. package/dist/types/cipher.d.ts +27 -0
  105. package/dist/types/cipher.js +7 -0
  106. package/{types → dist/types}/common.d.ts +8 -33
  107. package/dist/types/common.js +5 -0
  108. package/{types → dist/types}/context.d.ts +2 -4
  109. package/dist/types/context.js +4 -0
  110. package/{types → dist/types}/crypto.d.ts +0 -3
  111. package/dist/types/crypto.js +4 -0
  112. package/dist/types/database.d.ts +138 -0
  113. package/dist/types/database.js +4 -0
  114. package/dist/types/hook.d.ts +15 -0
  115. package/dist/types/hook.js +6 -0
  116. package/dist/types/jwt.d.ts +75 -0
  117. package/dist/types/jwt.js +4 -0
  118. package/dist/types/logger.d.ts +47 -0
  119. package/dist/types/logger.js +6 -0
  120. package/dist/types/plugin.d.ts +14 -0
  121. package/dist/types/plugin.js +6 -0
  122. package/dist/types/redis.d.ts +71 -0
  123. package/dist/types/redis.js +4 -0
  124. package/{types/roleApisCache.ts → dist/types/roleApisCache.d.ts} +0 -2
  125. package/dist/types/roleApisCache.js +8 -0
  126. package/dist/types/sync.d.ts +92 -0
  127. package/dist/types/sync.js +4 -0
  128. package/dist/types/table.d.ts +34 -0
  129. package/dist/types/table.js +4 -0
  130. package/dist/types/validate.d.ts +67 -0
  131. package/dist/types/validate.js +4 -0
  132. package/dist/utils/arrayKeysToCamel.d.ts +13 -0
  133. package/{utils/arrayKeysToCamel.ts → dist/utils/arrayKeysToCamel.js} +5 -5
  134. package/dist/utils/calcPerfTime.d.ts +4 -0
  135. package/{utils/calcPerfTime.ts → dist/utils/calcPerfTime.js} +3 -3
  136. package/dist/utils/configTypes.d.ts +1 -0
  137. package/dist/utils/configTypes.js +1 -0
  138. package/dist/utils/convertBigIntFields.d.ts +11 -0
  139. package/{utils/convertBigIntFields.ts → dist/utils/convertBigIntFields.js} +5 -9
  140. package/dist/utils/cors.d.ts +8 -0
  141. package/{utils/cors.ts → dist/utils/cors.js} +1 -3
  142. package/dist/utils/disableMenusGlob.d.ts +13 -0
  143. package/{utils/disableMenusGlob.ts → dist/utils/disableMenusGlob.js} +9 -29
  144. package/dist/utils/fieldClear.d.ts +11 -0
  145. package/{utils/fieldClear.ts → dist/utils/fieldClear.js} +15 -33
  146. package/dist/utils/genShortId.d.ts +10 -0
  147. package/{utils/genShortId.ts → dist/utils/genShortId.js} +1 -1
  148. package/dist/utils/getClientIp.d.ts +6 -0
  149. package/{utils/getClientIp.ts → dist/utils/getClientIp.js} +1 -7
  150. package/dist/utils/importDefault.d.ts +1 -0
  151. package/dist/utils/importDefault.js +29 -0
  152. package/dist/utils/isDirentDirectory.d.ts +2 -0
  153. package/{utils/isDirentDirectory.ts → dist/utils/isDirentDirectory.js} +3 -8
  154. package/dist/utils/keysToCamel.d.ts +10 -0
  155. package/{utils/keysToCamel.ts → dist/utils/keysToCamel.js} +4 -5
  156. package/dist/utils/keysToSnake.d.ts +10 -0
  157. package/{utils/keysToSnake.ts → dist/utils/keysToSnake.js} +4 -5
  158. package/dist/utils/loadMenuConfigs.d.ts +5 -0
  159. package/{utils/loadMenuConfigs.ts → dist/utils/loadMenuConfigs.js} +24 -51
  160. package/dist/utils/pickFields.d.ts +4 -0
  161. package/{utils/pickFields.ts → dist/utils/pickFields.js} +2 -5
  162. package/dist/utils/process.d.ts +24 -0
  163. package/{utils/process.ts → dist/utils/process.js} +2 -18
  164. package/dist/utils/processFields.d.ts +4 -0
  165. package/{utils/processFields.ts → dist/utils/processFields.js} +5 -9
  166. package/dist/utils/regex.d.ts +145 -0
  167. package/{configs/presetRegexp.ts → dist/utils/regex.js} +8 -31
  168. package/dist/utils/response.d.ts +20 -0
  169. package/{utils/response.ts → dist/utils/response.js} +28 -49
  170. package/dist/utils/scanAddons.d.ts +17 -0
  171. package/{utils/scanAddons.ts → dist/utils/scanAddons.js} +6 -40
  172. package/dist/utils/scanConfig.d.ts +26 -0
  173. package/{utils/scanConfig.ts → dist/utils/scanConfig.js} +22 -59
  174. package/dist/utils/scanFiles.d.ts +30 -0
  175. package/{utils/scanFiles.ts → dist/utils/scanFiles.js} +26 -66
  176. package/dist/utils/scanSources.d.ts +10 -0
  177. package/dist/utils/scanSources.js +41 -0
  178. package/dist/utils/sortModules.d.ts +28 -0
  179. package/{utils/sortModules.ts → dist/utils/sortModules.js} +25 -65
  180. package/dist/utils/sqlLog.d.ts +14 -0
  181. package/{utils/sqlLog.ts → dist/utils/sqlLog.js} +2 -14
  182. package/package.json +14 -28
  183. package/.gitignore +0 -0
  184. package/bunfig.toml +0 -3
  185. package/docs/README.md +0 -98
  186. package/docs/api/api.md +0 -1921
  187. package/docs/guide/examples.md +0 -926
  188. package/docs/guide/quickstart.md +0 -354
  189. package/docs/hooks/auth.md +0 -38
  190. package/docs/hooks/cors.md +0 -28
  191. package/docs/hooks/hook.md +0 -838
  192. package/docs/hooks/parser.md +0 -19
  193. package/docs/hooks/rateLimit.md +0 -47
  194. package/docs/infra/redis.md +0 -628
  195. package/docs/plugins/cipher.md +0 -61
  196. package/docs/plugins/database.md +0 -189
  197. package/docs/plugins/plugin.md +0 -986
  198. package/docs/reference/addon.md +0 -510
  199. package/docs/reference/config.md +0 -573
  200. package/docs/reference/logger.md +0 -495
  201. package/docs/reference/sync.md +0 -478
  202. package/docs/reference/table.md +0 -763
  203. package/docs/reference/validator.md +0 -620
  204. package/lib/asyncContext.ts +0 -43
  205. package/plugins/config.ts +0 -13
  206. package/plugins/jwt.ts +0 -15
  207. package/router/api.ts +0 -130
  208. package/tsconfig.json +0 -8
  209. package/types/database.d.ts +0 -541
  210. package/types/hook.d.ts +0 -25
  211. package/types/jwt.d.ts +0 -118
  212. package/types/logger.d.ts +0 -65
  213. package/types/plugin.d.ts +0 -19
  214. package/types/redis.d.ts +0 -83
  215. package/types/sync.d.ts +0 -398
  216. package/types/table.d.ts +0 -216
  217. package/types/validate.d.ts +0 -69
  218. package/utils/configTypes.ts +0 -3
  219. package/utils/importDefault.ts +0 -21
  220. package/utils/scanSources.ts +0 -64
package/README.md CHANGED
@@ -4,356 +4,132 @@
4
4
 
5
5
  > 道生一,一生二,二生三,三生万物
6
6
 
7
- **Befly 3.0 - TypeScript 重构版本已发布!**
7
+ 专为 Bun 运行时设计的 API 框架:插件化、自动同步、内置权限与缓存。
8
8
 
9
- ## 🎯 简介
9
+ ## 运行环境
10
10
 
11
- Befly 是专为 Bun 运行时设计的现代化 API 框架,提供:
11
+ - Bun >= 1.0
12
+ - MySQL >= 8.0(或 PostgreSQL / SQLite)
13
+ - Redis >= 6.0(可选,但推荐)
12
14
 
13
- - ⚡ **原生 TypeScript 支持** - 完整的类型定义和智能提示
14
- - 🚀 **高性能** - 基于 Bun 运行时,超快的启动和执行速度
15
- - 🔌 **插件化架构** - 灵活的插件系统,轻松扩展功能
16
- - 🗄️ **多数据库支持** - MySQL、PostgreSQL、SQLite 统一接口
17
- - 📝 **自动化表管理** - 基于 JSON 的表定义,自动同步数据库结构
18
- - 🔐 **内置身份验证** - JWT 认证,角色权限管理
19
- - 📊 **完整日志系统** - 结构化日志,敏感字段过滤
15
+ ## 安装与启动
20
16
 
21
- ## 📦 快速开始
17
+ ### 1) 安装
22
18
 
23
- ### 安装
19
+ 在你的项目里安装:
24
20
 
25
21
  ```bash
26
- # 创建新项目
27
- mkdir my-api && cd my-api
28
-
29
- # 安装 Befly
30
22
  bun add befly
31
-
32
- # 初始化项目(即将支持)
33
- bunx befly init
34
- ```
35
-
36
- ### 最简示例
37
-
38
- ```typescript
39
- // main.ts
40
- import { Befly } from "befly";
41
-
42
- const app = new Befly({
43
- appName: "My API",
44
- appPort: 3000
45
- });
46
-
47
- await app.start();
48
- ```
49
-
50
- 运行项目:
51
-
52
- ```bash
53
- bun run main.ts
54
- ```
55
-
56
- ### 创建第一个接口
57
-
58
- ```typescript
59
- // apis/user/hello.ts
60
- import type { ApiRoute } from "befly/types/api";
61
-
62
- export default {
63
- name: "问候接口",
64
- auth: false, // 公开接口
65
- fields: {},
66
- handler: async (befly, ctx) => {
67
- return {
68
- msg: "Hello, Befly!",
69
- data: {
70
- timestamp: Date.now()
71
- }
72
- };
73
- }
74
- } as ApiRoute;
75
23
  ```
76
24
 
77
- 访问:`http://localhost:3000/api/user/hello`
78
-
79
- ## 🔥 新版本特性(3.0)
80
-
81
- ### TypeScript 全面支持
82
-
83
- ```typescript
84
- import type { ApiRoute } from "befly/types/api";
85
- import type { BeflyContext } from "befly/types/befly";
86
- import type { User } from "./types/models";
87
-
88
- export default {
89
- name: "获取用户",
90
- auth: true,
91
- fields: {
92
- id: "用户ID|number|1|999999|null|1|null"
93
- },
94
- required: ["id"],
95
- handler: async (befly: BeflyContext, ctx) => {
96
- const { id } = ctx.body;
97
-
98
- // 类型安全的数据库查询
99
- const user = await befly.db.getOne<User>({
100
- table: "user",
101
- where: { id }
102
- });
103
-
104
- return { msg: "查询成功", data: user };
105
- }
106
- } as ApiRoute;
25
+ ### 2) 项目结构(约定)
26
+
27
+ ```text
28
+ my-api/
29
+ ├── apis/ # 项目 API(扫描 ts/js)
30
+ │ └── user/
31
+ │ └── hello.ts
32
+ ├── tables/ # 表定义 JSON(可选)
33
+ │ └── user.json
34
+ ├── configs/ # 配置文件(必需)
35
+ │ ├── befly.common.json
36
+ │ ├── befly.development.json
37
+ │ └── befly.production.json
38
+ └── main.ts
107
39
  ```
108
40
 
109
- ### 增强的数据库操作
41
+ ### 3) 配置文件
110
42
 
111
- ```typescript
112
- // 查询单条
113
- const user = await befly.db.getOne<User>({
114
- table: "user",
115
- where: { id: 1 }
116
- });
117
-
118
- // 分页列表
119
- const result = await befly.db.getList<Product>({
120
- table: "product",
121
- where: { category: "electronics" },
122
- page: 1,
123
- limit: 10,
124
- orderBy: ["createdAt#DESC"]
125
- });
126
-
127
- // 插入数据
128
- await befly.db.insData({
129
- table: "user",
130
- data: {
131
- username: "john",
132
- email: "john@example.com"
133
- }
134
- });
135
-
136
- // 更新数据
137
- await befly.db.updData({
138
- table: "user",
139
- where: { id: 1 },
140
- data: {
141
- nickname: "John Doe"
142
- }
143
- });
144
-
145
- // 删除数据
146
- await befly.db.delData({
147
- table: "user",
148
- where: { id: 1 }
149
- });
150
- ```
151
-
152
- ### 智能表定义
43
+ `configs/befly.development.json` 示例:
153
44
 
154
45
  ```json
155
46
  {
156
- "username": "用户名|string|3|50|null|1|^[a-zA-Z0-9_]+$",
157
- "email": "邮箱|string|5|100|null|1|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
158
- "age": "年龄|number|0|150|18|0|null",
159
- "tags": "标签|array_string|0|10|null|0|null",
160
- "bio": "简介|text|0|5000|null|0|null"
161
- }
162
- ```
163
-
164
- 字段定义格式:`"字段名|类型|最小值|最大值|默认值|是否索引|正则约束"`
165
-
166
- 同步到数据库:
167
-
168
- 请参考:`docs/reference/sync.md`(`syncTable` / `syncData` 等同步流程说明)。
169
-
170
- ## 🗄️ 数据库配置
171
-
172
- 统一使用环境变量配置,支持三种数据库:
173
-
174
- ```bash
175
- # MySQL
176
- DB_TYPE=mysql
177
- DB_HOST=127.0.0.1
178
- DB_PORT=3306
179
- DB_USER=root
180
- DB_PASS=password
181
- DB_NAME=my_database
182
-
183
- # PostgreSQL
184
- DB_TYPE=postgresql
185
- DB_HOST=localhost
186
- DB_PORT=5432
187
- DB_USER=postgres
188
- DB_PASS=password
189
- DB_NAME=my_database
190
-
191
- # SQLite
192
- DB_TYPE=sqlite
193
- DB_NAME=/path/to/database.sqlite
194
- # 或使用内存数据库
195
- DB_NAME=:memory:
196
- ```
197
-
198
- ## ⚙️ 项目配置文件
199
-
200
- Befly 使用 `befly.config.ts` 作为统一配置文件:
201
-
202
- ```typescript
203
- // befly.config.ts
204
- export const beflyConfig = {
205
- appName: "我的应用",
206
- appPort: 3000,
207
- appHost: "0.0.0.0",
208
-
209
- // 数据库配置(优先使用环境变量)
210
- db: {
211
- type: "mysql",
212
- host: "127.0.0.1",
213
- port: 3306,
214
- username: "root",
215
- password: "password",
216
- database: "my_database"
217
- },
218
-
219
- // Redis 配置
220
- redis: {
221
- host: "127.0.0.1",
222
- port: 6379,
223
- prefix: "befly"
47
+ "appName": "My API",
48
+ "appPort": 3000,
49
+ "appHost": "127.0.0.1",
50
+
51
+ "db": {
52
+ "type": "mysql",
53
+ "host": "127.0.0.1",
54
+ "port": 3306,
55
+ "username": "root",
56
+ "password": "root",
57
+ "database": "my_api"
224
58
  },
225
59
 
226
- // CORS 跨域配置
227
- cors: {
228
- origin: ["http://localhost:5173"],
229
- methods: ["GET", "POST", "PUT", "DELETE"]
60
+ "redis": {
61
+ "host": "127.0.0.1",
62
+ "port": 6379,
63
+ "db": 0,
64
+ "prefix": "my_api"
230
65
  },
231
66
 
232
- // Addon 插件配置
233
- addons: {
234
- admin: {
235
- email: { host: "smtp.qq.com" }
236
- }
67
+ "auth": {
68
+ "secret": "change-me",
69
+ "expiresIn": "7d",
70
+ "algorithm": "HS256"
237
71
  }
238
- };
72
+ }
239
73
  ```
240
74
 
241
- > 注意:`redis.prefix` 不要包含 `:`(系统会自动拼接分隔符)。
242
-
243
- ### 数据库连接
244
-
245
- 通常你不需要手动连接(框架启动期会完成连接并注入插件实例)。
75
+ > 注意:`redis.prefix` 不要包含 `:`,框架会自动拼接分隔符。
246
76
 
247
- 如果你在自定义脚本/测试中需要手动连接,请显式传入配置片段(不要依赖全局单例配置):
77
+ ### 4) 启动入口
248
78
 
249
79
  ```typescript
250
- import { Connect } from "befly/lib/connect";
251
-
252
- // 连接 SQL 数据库
253
- await Connect.connectSql({
254
- type: "mysql",
255
- host: "127.0.0.1",
256
- port: 3306,
257
- username: "root",
258
- password: "root",
259
- database: "befly_demo",
260
- poolMax: 1
261
- });
262
-
263
- // 连接 Redis
264
- await Connect.connectRedis({
265
- host: "127.0.0.1",
266
- port: 6379,
267
- db: 0,
268
- prefix: "befly"
269
- });
270
-
271
- // 或:同时连接 SQL 和 Redis
272
- await Connect.connect({
273
- db: {
274
- type: "mysql",
275
- host: "127.0.0.1",
276
- port: 3306,
277
- username: "root",
278
- password: "root",
279
- database: "befly_demo",
280
- poolMax: 1
281
- },
282
- redis: {
283
- host: "127.0.0.1",
284
- port: 6379,
285
- db: 0,
286
- prefix: "befly"
287
- }
288
- });
289
-
290
- // 获取连接状态
291
- const status = Connect.getStatus();
292
- console.log(status.sql.connected); // true/false
293
- console.log(status.redis.connected); // true/false
80
+ // main.ts
81
+ import { Befly } from "befly";
294
82
 
295
- // 断开连接
296
- await Connect.disconnect();
83
+ const app = new Befly();
84
+ await app.start();
297
85
  ```
298
86
 
299
- ### 配置文件(当前约定)
300
-
301
- 配置文件名为 `befly.config.ts`,导出名为 `beflyConfig`:
87
+ ## 编写第一个 API
302
88
 
303
89
  ```typescript
304
- export const beflyConfig = {
305
- // ...
306
- };
90
+ // apis/user/hello.ts
91
+ import type { ApiRoute } from "befly/types/api";
92
+
93
+ export default {
94
+ name: "问候接口",
95
+ auth: false,
96
+ handler: async (_befly, _ctx) => {
97
+ return { code: 0, msg: "Hello, Befly!", data: { ts: Date.now() } };
98
+ }
99
+ } as ApiRoute;
307
100
  ```
308
101
 
309
- ## 📖 文档
102
+ 启动后访问:
310
103
 
311
- 完整文档请访问 [`/docs` 目录](./docs/):
104
+ - `GET http://localhost:3000/api/app/user/hello`
312
105
 
313
- - [快速开始](./docs/02-快速上手/01-10分钟体验.md)
314
- - [核心概念](./docs/03-核心概念/)
315
- - [API 开发](./docs/04-API开发/)
316
- - [数据库操作](./docs/05-数据库/)
317
- - [TypeScript 支持](./docs/10-TypeScript/01-TypeScript支持.md)
106
+ ## 路由规则(重要)
318
107
 
319
- ### 目录说明
108
+ Befly 会根据“来源 + 文件相对路径”生成 `routePath`:
320
109
 
321
- - **`packages/core`** - Befly 核心框架包(发布到 npm)
322
- - **`packages/tpl`** - API 项目模板示例
323
- - **`packages/admin`** - 后台管理系统(Vue3 + TDesign Vue Next + 自动导入)
110
+ - 项目 API:`apis/**/*.{ts,js}` `/api/app/...`
111
+ - Addon API
112
+ - `addons/<addonName>/apis/**/*.{ts,js}` `/api/addon/<addonName>/...`
113
+ - `node_modules/@befly-addon/<addonName>/apis/**/*.{ts,js}` → `/api/addon/<addonName>/...`
324
114
 
325
- ## 🚀 快速启动
115
+ 并且:
326
116
 
327
- ### 启动 API 服务
117
+ - 系统内部用于存储/权限判断的 `routePath` **只看 `url.pathname`**(例如 `/api/app/user/login`)。
118
+ - **禁止**把权限写成 `POST /api/...` 或 `POST/api/...`(那只是请求行展示,不参与存储)。
328
119
 
329
- ```bash
330
- bun run dev
331
- # 访问: http://localhost:3000
332
- ```
120
+ ## TypeScript 类型导入(public types)
333
121
 
334
- ### 启动后台管理
122
+ 只从 `befly/types/*` 子路径引入类型:
335
123
 
336
- ```bash
337
- bun run dev:admin
338
- # 访问: http://localhost:5173
124
+ ```typescript
125
+ import type { ApiRoute } from "befly/types/api";
126
+ import type { BeflyContext } from "befly/types/befly";
339
127
  ```
340
128
 
341
- ## 🎓 示例项目
342
-
343
- 查看 `/tpl` 目录获取完整的示例项目。
344
-
345
- ## 🤝 贡献
346
-
347
- 欢迎提交 Issue 和 Pull Request!
348
-
349
- ## 📄 许可
350
-
351
- MIT License
352
-
353
- ## 🌟 致谢
354
-
355
- 感谢所有为 Befly 做出贡献的开发者!
129
+ ## 文档
356
130
 
357
- ---
131
+ 更多细节请看 `packages/core/docs/`:
358
132
 
359
- **Befly 3.0 - 让 API 开发更简单、更高效!** 🚀
133
+ - `docs/guide/quickstart.md`
134
+ - `docs/reference/sync.md`
135
+ - `docs/plugins/plugin.md`
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Befly 配置模块
3
+ * 自动加载 configs 目录下的配置文件并与默认配置合并
4
+ * 支持环境分离:befly.common.json + befly.development/production.json
5
+ */
6
+ import type { BeflyOptions } from "./types/befly.ts";
7
+ export declare function loadBeflyConfig(): Promise<BeflyOptions>;
@@ -1,15 +1,7 @@
1
- /**
2
- * Befly 配置模块
3
- * 自动加载 configs 目录下的配置文件并与默认配置合并
4
- * 支持环境分离:befly.common.json + befly.development/production.json
5
- */
6
- import type { BeflyOptions } from "./types/befly.ts";
7
-
8
- import { compileDisableMenuGlobRules } from "./utils/disableMenusGlob.ts";
9
- import { scanConfig } from "./utils/scanConfig.ts";
10
-
1
+ import { compileDisableMenuGlobRules } from "./utils/disableMenusGlob.js";
2
+ import { scanConfig } from "./utils/scanConfig.js";
11
3
  /** 默认配置 */
12
- const defaultOptions: BeflyOptions = {
4
+ const defaultOptions = {
13
5
  // ========== 核心参数 ==========
14
6
  nodeEnv: "development",
15
7
  appName: "野蜂飞舞",
@@ -19,7 +11,6 @@ const defaultOptions: BeflyOptions = {
19
11
  devPassword: "beflydev123456",
20
12
  bodyLimit: 1048576, // 1MB
21
13
  tz: "Asia/Shanghai",
22
-
23
14
  // ========== 日志配置 ==========
24
15
  logger: {
25
16
  debug: 1,
@@ -30,7 +21,6 @@ const defaultOptions: BeflyOptions = {
30
21
  maxStringLen: 100,
31
22
  maxArrayItems: 100
32
23
  },
33
-
34
24
  // ========== 数据库配置 ==========
35
25
  db: {
36
26
  type: "mysql",
@@ -41,7 +31,6 @@ const defaultOptions: BeflyOptions = {
41
31
  database: "befly_demo",
42
32
  poolMax: 10
43
33
  },
44
-
45
34
  // ========== Redis 配置 ==========
46
35
  redis: {
47
36
  host: "127.0.0.1",
@@ -51,14 +40,12 @@ const defaultOptions: BeflyOptions = {
51
40
  db: 0,
52
41
  prefix: "befly_demo"
53
42
  },
54
-
55
43
  // ========== 认证配置 ==========
56
44
  auth: {
57
45
  secret: "befly-secret",
58
46
  expiresIn: "7d",
59
47
  algorithm: "HS256"
60
48
  },
61
-
62
49
  // ========== CORS 配置 ==========
63
50
  cors: {
64
51
  origin: "*",
@@ -68,7 +55,6 @@ const defaultOptions: BeflyOptions = {
68
55
  maxAge: 86400,
69
56
  credentials: "true"
70
57
  },
71
-
72
58
  // ========== Hook:全局限流 ==========
73
59
  rateLimit: {
74
60
  enable: 1,
@@ -79,28 +65,22 @@ const defaultOptions: BeflyOptions = {
79
65
  skipRoutes: [],
80
66
  rules: []
81
67
  },
82
-
83
68
  // ========== 禁用配置 ==========
84
69
  disableHooks: [],
85
70
  disablePlugins: [],
86
71
  disableMenus: ["**/404", "**/403", "**/500", "**/login"],
87
-
88
72
  // ========== Addon 配置 ==========
89
73
  addons: {}
90
74
  };
91
-
92
- const beflyConfigCache: Map<string, Promise<BeflyOptions>> = new Map();
93
-
94
- export async function loadBeflyConfig(): Promise<BeflyOptions> {
75
+ const beflyConfigCache = new Map();
76
+ export async function loadBeflyConfig() {
95
77
  const nodeEnv = process.env.NODE_ENV || defaultOptions.nodeEnv || "development";
96
78
  const envSuffix = nodeEnv === "production" ? "production" : "development";
97
-
98
79
  const cacheKey = nodeEnv;
99
80
  const cached = beflyConfigCache.get(cacheKey);
100
81
  if (cached) {
101
82
  return await cached;
102
83
  }
103
-
104
84
  const promise = (async () => {
105
85
  // 使用 scanConfig 一次性加载并合并所有配置文件
106
86
  // 合并顺序:defaultOptions ← befly.common.json ← befly.development/production.json
@@ -111,30 +91,27 @@ export async function loadBeflyConfig(): Promise<BeflyOptions> {
111
91
  mode: "merge",
112
92
  defaults: defaultOptions
113
93
  });
114
-
115
94
  // 配置校验:redis.prefix 作为 key 前缀,由 RedisHelper 统一拼接 ":"。
116
95
  // 因此 prefix 本身不允许包含 ":",否则会导致 key 结构出现空段或多段分隔(例如 "prefix::key"),
117
96
  // 在 RedisInsight 等工具里可能显示 [NO NAME] 空分组,且容易造成 key 管理混乱。
118
- const redisPrefix = (config as any)?.redis?.prefix;
97
+ const redisPrefix = config?.redis?.prefix;
119
98
  if (typeof redisPrefix === "string") {
120
99
  const trimmedPrefix = redisPrefix.trim();
121
100
  if (trimmedPrefix.includes(":")) {
122
101
  throw new Error(`配置错误:redis.prefix 不允许包含 ':'(RedisHelper 会自动拼接分隔符 ':'),请改为不带冒号的前缀,例如 'befly_demo',当前值=${redisPrefix}`);
123
102
  }
124
103
  }
125
-
126
104
  // 预编译 disableMenus 的 Bun.Glob 规则:
127
105
  // - 提前暴露配置错误(fail-fast)
128
106
  // - 后续 checkMenu 会复用同一进程级缓存
129
- compileDisableMenuGlobRules((config as any)?.disableMenus);
130
-
131
- return config as BeflyOptions;
107
+ compileDisableMenuGlobRules(config?.disableMenus);
108
+ return config;
132
109
  })();
133
-
134
110
  beflyConfigCache.set(cacheKey, promise);
135
111
  try {
136
112
  return await promise;
137
- } catch (error: any) {
113
+ }
114
+ catch (error) {
138
115
  beflyConfigCache.delete(cacheKey);
139
116
  throw error;
140
117
  }
@@ -0,0 +1 @@
1
+ export declare function checkApi(apis: any[]): Promise<void>;
@@ -1,11 +1,8 @@
1
1
  import { isPlainObject } from "es-toolkit/compat";
2
2
  import { omit } from "es-toolkit/object";
3
-
4
- import { Logger } from "../lib/logger.ts";
5
-
6
- export async function checkApi(apis: any[]): Promise<void> {
3
+ import { Logger } from "../lib/logger.js";
4
+ export async function checkApi(apis) {
7
5
  let hasError = false;
8
-
9
6
  for (const api of apis) {
10
7
  try {
11
8
  if (typeof api?.name !== "string" || api.name.trim() === "") {
@@ -13,83 +10,69 @@ export async function checkApi(apis: any[]): Promise<void> {
13
10
  hasError = true;
14
11
  continue;
15
12
  }
16
-
17
13
  if (typeof api?.handler !== "function") {
18
14
  Logger.warn(omit(api, ["handler"]), "接口的 handler 属性必须是函数");
19
15
  hasError = true;
20
16
  continue;
21
17
  }
22
-
23
18
  // routePath / routePrefix 由 scanFiles 系统生成:必须是严格的 pathname
24
19
  if (typeof api?.routePath !== "string" || api.routePath.trim() === "") {
25
20
  Logger.warn(omit(api, ["handler"]), "接口的 routePath 属性必须是非空字符串(由系统生成)");
26
21
  hasError = true;
27
- } else {
22
+ }
23
+ else {
28
24
  const routePath = api.routePath.trim();
29
-
30
25
  // 不允许出现 "POST/api/..." 等 method 前缀
31
26
  if (/^(GET|POST|PUT|PATCH|DELETE|OPTIONS|HEAD)\b/i.test(routePath)) {
32
27
  Logger.warn(omit(api, ["handler"]), "接口的 routePath 不允许包含 method 前缀,应为 url.pathname(例如 /api/app/xxx)");
33
28
  hasError = true;
34
29
  }
35
-
36
30
  if (!routePath.startsWith("/api/")) {
37
31
  Logger.warn(omit(api, ["handler"]), "接口的 routePath 必须以 /api/ 开头");
38
32
  hasError = true;
39
33
  }
40
-
41
34
  if (routePath.includes(" ")) {
42
35
  Logger.warn(omit(api, ["handler"]), "接口的 routePath 不允许包含空格");
43
36
  hasError = true;
44
37
  }
45
-
46
38
  if (routePath.includes("/api//")) {
47
39
  Logger.warn(omit(api, ["handler"]), "接口的 routePath 不允许出现 /api//(重复斜杠)");
48
40
  hasError = true;
49
41
  }
50
42
  }
51
-
52
43
  if (typeof api?.routePrefix !== "string" || api.routePrefix.trim() === "") {
53
44
  Logger.warn(omit(api, ["handler"]), "接口的 routePrefix 属性必须是非空字符串(由系统生成)");
54
45
  hasError = true;
55
46
  }
56
-
57
47
  if (api.method && !["GET", "POST", "GET,POST", "POST,GET"].includes(String(api.method).toUpperCase())) {
58
48
  Logger.warn(omit(api, ["handler"]), "接口的 method 属性必须是有效的 HTTP 方法 (GET, POST, GET,POST, POST,GET)");
59
49
  hasError = true;
60
50
  }
61
-
62
51
  if (api.auth !== undefined && typeof api.auth !== "boolean") {
63
52
  Logger.warn(omit(api, ["handler"]), "接口的 auth 属性必须是布尔值 (true=需登录, false=公开)");
64
53
  hasError = true;
65
54
  }
66
-
67
55
  if (api.fields && !isPlainObject(api.fields)) {
68
56
  Logger.warn(omit(api, ["handler"]), "接口的 fields 属性必须是对象");
69
57
  hasError = true;
70
58
  }
71
-
72
59
  if (api.required && !Array.isArray(api.required)) {
73
60
  Logger.warn(omit(api, ["handler"]), "接口的 required 属性必须是数组");
74
61
  hasError = true;
75
62
  }
76
-
77
- if (api.required && api.required.some((reqItem: any) => typeof reqItem !== "string")) {
63
+ if (api.required && api.required.some((reqItem) => typeof reqItem !== "string")) {
78
64
  Logger.warn(omit(api, ["handler"]), "接口的 required 属性必须是字符串数组");
79
65
  hasError = true;
80
66
  }
81
- } catch (error: any) {
82
- Logger.error(
83
- {
84
- err: error,
85
- item: api
86
- },
87
- "接口解析失败"
88
- );
67
+ }
68
+ catch (error) {
69
+ Logger.error({
70
+ err: error,
71
+ item: api
72
+ }, "接口解析失败");
89
73
  hasError = true;
90
74
  }
91
75
  }
92
-
93
76
  if (hasError) {
94
77
  throw new Error("接口结构检查失败");
95
78
  }
@@ -0,0 +1 @@
1
+ export declare function checkHook(hooks: any[]): Promise<void>;