befly 3.10.0 → 3.10.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.
@@ -98,8 +98,8 @@ Logger.info("用户登录成功");
98
98
  Logger.info({ userId: 123 }, "用户登录成功");
99
99
 
100
100
  // 警告日志
101
- Logger.warn("配置项已弃用");
102
- Logger.warn({ config: "oldOption" }, "配置项已弃用");
101
+ Logger.warn("配置项不合法");
102
+ Logger.warn({ config: "oldOption" }, "配置项不合法");
103
103
 
104
104
  // 错误日志
105
105
  Logger.error("数据库连接失败");
@@ -393,7 +393,7 @@ Logger.debug({ sql: query, params: params }, "SQL 查询");
393
393
  Logger.info({ userId: 123 }, "用户登录成功");
394
394
 
395
395
  // warn: 潜在问题,但不影响功能
396
- Logger.warn({ config: "deprecated" }, "配置项已弃用");
396
+ Logger.warn({ config: "invalidOption" }, "配置项不合法");
397
397
 
398
398
  // error: 操作失败
399
399
  Logger.error({ err: error }, "数据库连接失败");
@@ -5,10 +5,12 @@
5
5
  ## 目录
6
6
 
7
7
  - [概述](#概述)
8
+ - [强约束清单](#强约束清单)
8
9
  - [syncTable 数据库同步](#synctable-数据库同步)
9
10
  - [syncApi 接口同步](#syncapi-接口同步)
10
11
  - [syncMenu 菜单同步](#syncmenu-菜单同步)
11
12
  - [syncDev 开发账户同步](#syncdev-开发账户同步)
13
+ - [syncCache 缓存同步](#synccache-缓存同步)
12
14
  - [表名规则](#表名规则)
13
15
  - [注意事项](#注意事项)
14
16
  - [FAQ](#faq)
@@ -25,8 +27,18 @@ Sync 同步系统用于将代码定义同步到数据库,包括:
25
27
  | `syncApi` | 同步 API 路由信息 | `addon_admin_api` |
26
28
  | `syncMenu` | 同步菜单配置 | `addon_admin_menu` |
27
29
  | `syncDev` | 创建开发者账户 | `addon_admin_role`, `addon_admin_admin` |
30
+ | `syncCache` | 同步缓存 | Redis(apis/menu/role-permissions) |
28
31
 
29
- **执行顺序**:`syncTable` → `syncApi` → `syncMenu` → `syncDev`
32
+ **执行顺序**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
33
+
34
+ ---
35
+
36
+ ## 强约束清单
37
+
38
+ - **API routePath 必须是 pathname**:`syncApi` 写入数据库的 `routePath` 仅允许 `url.pathname`(例如 `/api/user/login`),禁止出现 method 前缀(`POST/api/...`、`POST /api/...`)。
39
+ - **角色权限 apis 仅允许 pathname 字符串数组**:`syncDev` 写入角色表的 `apis` 必须是 pathname 字符串数组(严格模式不允许 numeric id)。
40
+ - **权限缓存 Set member 仅允许 pathname**:角色接口权限缓存的 Set 成员为 pathname,与 method 无关。
41
+ - **Redis prefix 不允许包含冒号**:配置 `redis.prefix` 不要包含 `:`(系统会自动拼接分隔符)。例如写 `befly`,不要写 `befly:`。
30
42
 
31
43
  > 说明:当前版本不提供 CLI 同步命令;同步逻辑在服务启动时由主进程自动执行(见 `packages/core/main.ts`)。
32
44
 
@@ -44,7 +56,7 @@ Sync 同步系统用于将代码定义同步到数据库,包括:
44
56
  import { syncTable } from "../sync/syncTable.js";
45
57
  import { scanSources } from "../utils/scanSources.js";
46
58
 
47
- // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
59
+ // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
48
60
  const sources = await scanSources();
49
61
  await syncTable(ctx, sources.tables);
50
62
  ```
@@ -103,14 +115,16 @@ await syncTable(ctx, sources.tables);
103
115
 
104
116
  ### 基本用法
105
117
 
106
- 通常无需单独调用:`syncData()` 会按顺序执行 `syncApi` → `syncMenu` → `syncDev`。
118
+ 通常无需单独调用:服务启动流程会按顺序执行 `syncTable` `syncApi` → `syncMenu` → `syncDev` → `syncCache`。
107
119
 
108
- 如需在代码中手动触发整套数据同步:
120
+ 如需在代码中手动调用:
109
121
 
110
122
  ```typescript
111
- import { syncData } from "../sync/syncData.js";
123
+ import { syncApi } from "../sync/syncApi.js";
124
+ import { scanSources } from "../utils/scanSources.js";
112
125
 
113
- await syncData();
126
+ const sources = await scanSources();
127
+ await syncApi(ctx, sources.apis as any);
114
128
  ```
115
129
 
116
130
  ### 同步逻辑
@@ -137,20 +151,15 @@ await syncData();
137
151
  └─────────────────────────────────────────────────────┘
138
152
  ```
139
153
 
140
- ### API 信息提取
154
+ ### 存储字段(重要)
141
155
 
142
- API 文件中提取以下信息:
156
+ `syncApi` 会把扫描到的 API 信息同步到 `addon_admin_api` 表,核心字段为:
143
157
 
144
- ```typescript
145
- interface ApiInfo {
146
- name: string; // 接口名称(name 属性)
147
- path: string; // 路由路径(由文件路径生成)
148
- method: string; // 请求方法(method 属性,默认 POST
149
- description: string; // 接口描述(desc 属性)
150
- addonName: string; // 所属 Addon 名称
151
- addonTitle: string; // Addon 标题
152
- }
153
- ```
158
+ - `routePath`:只存 `url.pathname`(例如 `/api/user/login`),与 method 无关
159
+ - `name`:接口名称
160
+ - `addonName`:所属 addon(无 addon 时为空字符串)
161
+
162
+ > 注意:`routePath` 必须是 pathname(以 `/` 开头),不允许写成 `POST /api/...` 或 `POST/api/...`。
154
163
 
155
164
  ### 统计信息
156
165
 
@@ -171,7 +180,19 @@ interface SyncApiStats {
171
180
 
172
181
  ### 基本用法
173
182
 
174
- 同 `syncApi`,通常由 `syncData()` 统一触发。
183
+ 同 `syncApi`,通常由启动流程统一触发。
184
+
185
+ 如需手动调用,需要先对菜单配置做校验/过滤(例如 disableMenus):
186
+
187
+ ```typescript
188
+ import { checkMenu } from "../checks/checkMenu.js";
189
+ import { syncMenu } from "../sync/syncMenu.js";
190
+ import { scanSources } from "../utils/scanSources.js";
191
+
192
+ const sources = await scanSources();
193
+ const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
194
+ await syncMenu(ctx, checkedMenus);
195
+ ```
175
196
 
176
197
  ### 菜单配置文件
177
198
 
@@ -256,49 +277,56 @@ interface SyncMenuStats {
256
277
 
257
278
  ### 基本用法
258
279
 
259
- 同 `syncApi`,通常由 `syncData()` 统一触发。
280
+ 同 `syncApi`,通常由启动流程统一触发。
260
281
 
261
282
  ### 同步逻辑
262
283
 
263
284
  ```
264
285
  ┌─────────────────────────────────────────────────────┐
265
- syncDev
286
+ syncDev
266
287
  ├─────────────────────────────────────────────────────┤
267
- 1. 创建/更新开发角色:
268
- - 角色名称:开发者
269
- - 角色标识:dev
270
- - 权限:所有菜单 + 所有 API
271
-
272
- 2. 获取所有菜单 ID 列表
273
-
274
- 3. 获取所有 API ID 列表
275
-
276
- 4. 更新角色权限:
277
- - menus: 所有菜单 ID
278
- - apis: 所有 API ID │
279
-
280
- 5. 创建/更新开发管理员:
281
- - 用户名:dev
282
- - 密码:从配置读取
283
- - 角色:开发者角色
288
+ 1. 创建/更新开发角色:
289
+ - 角色名称:开发者
290
+ - 角色标识:dev
291
+ - 权限:所有菜单 + 所有 API
292
+
293
+ 2. 获取所有菜单 path 列表
294
+
295
+ 3. 获取所有 API routePath 列表
296
+
297
+ 4. 更新角色权限:
298
+ - menus: 所有菜单 path(字符串数组)
299
+ - apis: 所有 API routePath(pathname 字符串数组)│
300
+
301
+ 5. 创建/更新开发管理员:
302
+ - 用户名:dev
303
+ - 密码:从配置读取
304
+ - 角色:开发者角色
284
305
  └─────────────────────────────────────────────────────┘
285
306
  ```
286
307
 
287
308
  ### 配置说明
288
309
 
289
- 开发账户配置在 `befly.config.ts` 或环境配置文件中:
310
+ 开发账户配置在 `befly.config.ts` 或环境配置文件中(仅当 `devPassword` 有值时才会创建 dev 账号):
290
311
 
291
- ```typescript
292
- // befly.config.ts
293
- export default {
294
- dev: {
295
- username: "dev", // 开发账户用户名
296
- password: "dev123456" // 开发账户密码
297
- }
298
- };
312
+ ```json
313
+ {
314
+ "devEmail": "dev@qq.com",
315
+ "devPassword": "beflydev123456"
316
+ }
299
317
  ```
300
318
 
301
- await syncTable(ctx, sources.tables);
319
+ > 注意:`syncDev` 会把 `menus/apis` 写入角色表,并且 `apis` 必须是 pathname 字符串数组(严格模式下不允许 numeric id)。
320
+
321
+ ---
322
+
323
+ ## syncCache 缓存同步
324
+
325
+ 同步缓存(统一收敛到启动流程末尾执行):
326
+
327
+ - `cacheApis()`:缓存接口列表
328
+ - `cacheMenus()`:缓存菜单列表
329
+ - `rebuildRoleApiPermissions()`:重建角色接口权限 Set(member 为 pathname,与 method 无关)
302
330
 
303
331
  ---
304
332
 
@@ -306,16 +334,23 @@ await syncTable(ctx, sources.tables);
306
334
 
307
335
  ```typescript
308
336
  import { syncTable } from "./sync/syncTable.js";
337
+ import { syncApi } from "./sync/syncApi.js";
338
+ import { syncCache } from "./sync/syncCache.js";
339
+ import { syncDev } from "./sync/syncDev.js";
340
+ import { syncMenu } from "./sync/syncMenu.js";
309
341
  import { scanSources } from "./utils/scanSources.js";
310
- import { syncData } from "./sync/syncData";
342
+ import { checkMenu } from "./checks/checkMenu.js";
311
343
 
312
344
  // 启动前/启动中手动触发同步
313
- // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
345
+ // ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
314
346
  const sources = await scanSources();
315
- await syncTable(ctx, sources.tables);
316
- await syncData();
347
+ const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
317
348
 
318
- // 说明:syncData 内部会固定顺序执行:syncApi → syncMenu → syncDev
349
+ await syncTable(ctx, sources.tables);
350
+ await syncApi(ctx, sources.apis as any);
351
+ await syncMenu(ctx, checkedMenus);
352
+ await syncDev(ctx, { devEmail: ctx.config.devEmail, devPassword: ctx.config.devPassword });
353
+ await syncCache(ctx);
319
354
  ```
320
355
 
321
356
  ---
@@ -357,7 +392,7 @@ addons/demo/tables/article.json → addon_demo_article
357
392
 
358
393
  ### 1. 执行顺序
359
394
 
360
- **必须按顺序执行**:`syncTable` → `syncApi` → `syncMenu` → `syncDev`
395
+ **必须按顺序执行**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
361
396
 
362
397
  - `syncApi` 依赖 `addon_admin_api` 表(由 `syncTable` 创建)
363
398
  - `syncMenu` 依赖 `addon_admin_menu` 表(由 `syncTable` 创建)
@@ -386,11 +421,10 @@ CacheKeys.tableColumns(tableName); // table:columns:{tableName}
386
421
 
387
422
  ### 4. 连接管理
388
423
 
389
- Sync 命令会自动管理数据库和 Redis 连接:
424
+ `sync*` 函数本身不会负责建立连接/加载插件:
390
425
 
391
- - 执行前建立连接
392
- - 执行后关闭连接
393
- - 出错时正确清理资源
426
+ - 你需要在调用前确保 `Connect.connect(...)` 已执行,并且 `Db/Redis/cache` 插件已注入到 `ctx`。
427
+ - 服务启动流程已内置这套顺序(见 `packages/core/main.ts`)。
394
428
 
395
429
  ---
396
430
 
@@ -425,28 +459,20 @@ A: Addon 表名格式为 `addon_{addonName}_{tableName}`,建议:
425
459
 
426
460
  A:
427
461
 
428
- 1. 检查错误日志确定失败原因
429
- A: `syncTable()` 会跳过长度收缩并告警;请手动评估并处理(例如先清理/截断数据,再手动执行 DDL),再重新启动服务或再次调用 `syncTable()`。
462
+ 1. 检查错误日志确定失败原因(例如表不存在、字段变更被跳过等)
430
463
  2. sync 命令是幂等的,可以安全地多次执行
431
464
 
432
465
  ### Q: 如何只同步某个 Addon 的表?
433
466
 
434
- await syncTable(ctx, sources.tables);
435
467
  A: 当前不支持按 Addon 或单表筛选;会同步项目与所有 Addon 的表定义。
436
468
 
437
469
  ### Q: 开发账户密码在哪里配置?
438
470
 
439
- A: 在配置文件中设置:
471
+ A: 在配置文件中设置(仅当 `devPassword` 有值时才会创建 dev 账号):
440
472
 
441
- ```typescript
442
- // befly.config.ts
443
- export default {
444
- dev: {
445
- username: "dev",
446
- password: "your_password"
447
- }
448
- };
473
+ ```json
474
+ {
475
+ "devEmail": "dev@qq.com",
476
+ "devPassword": "beflydev123456"
477
+ }
449
478
  ```
450
-
451
- (不再提供 CLI 参数/命令;按配置文件机制设置即可。)
452
- await syncTable(ctx, sources.tables);
@@ -567,7 +567,7 @@ await syncTable(ctx, sources.tables);
567
567
 
568
568
  ### 安全机制
569
569
 
570
- 1. **禁止危险类型变更**:不允许从 `BIGINT` 改为 `VARCHAR` 等不兼容变更
570
+ 1. **禁止危险类型变更**:不允许从 `BIGINT` 改为 `VARCHAR` 等高风险变更
571
571
  2. **长度收缩保护**:默认跳过长度收缩,避免数据截断
572
572
  3. **保留字段保护**:不允许定义系统保留字段
573
573
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.10.0",
4
- "gitHead": "faa8189c7d23cf45885c03d1425cba8f5bf45df9",
3
+ "version": "3.10.1",
4
+ "gitHead": "123125b9d7a6c26879a5b5c9d3ac05e2082141c6",
5
5
  "private": false,
6
6
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
7
7
  "keywords": [
@@ -63,7 +63,7 @@
63
63
  "typecheck": "bunx tsgo --noEmit"
64
64
  },
65
65
  "dependencies": {
66
- "befly-shared": "1.0.0",
66
+ "befly-shared": "1.3.0",
67
67
  "chalk": "^5.6.2",
68
68
  "es-toolkit": "^1.43.0",
69
69
  "fast-jwt": "^6.1.0",