befly 3.9.40 → 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.
- package/README.md +47 -19
- package/befly.config.ts +19 -2
- package/checks/checkApi.ts +79 -77
- package/checks/checkHook.ts +48 -0
- package/checks/checkMenu.ts +168 -0
- package/checks/checkPlugin.ts +48 -0
- package/checks/checkTable.ts +137 -183
- package/docs/README.md +17 -11
- package/docs/api/api.md +16 -2
- package/docs/guide/quickstart.md +31 -10
- package/docs/hooks/hook.md +2 -2
- package/docs/hooks/rateLimit.md +1 -1
- package/docs/infra/redis.md +26 -14
- package/docs/plugins/plugin.md +23 -21
- package/docs/quickstart.md +5 -328
- package/docs/reference/addon.md +0 -4
- package/docs/reference/config.md +14 -31
- package/docs/reference/logger.md +3 -3
- package/docs/reference/sync.md +132 -237
- package/docs/reference/table.md +28 -30
- package/hooks/auth.ts +3 -4
- package/hooks/cors.ts +4 -6
- package/hooks/parser.ts +3 -4
- package/hooks/permission.ts +3 -4
- package/hooks/validator.ts +3 -4
- package/lib/cacheHelper.ts +89 -153
- package/lib/cacheKeys.ts +1 -1
- package/lib/connect.ts +9 -13
- package/lib/dbDialect.ts +285 -0
- package/lib/dbHelper.ts +179 -507
- package/lib/dbUtils.ts +450 -0
- package/lib/logger.ts +41 -5
- package/lib/redisHelper.ts +1 -0
- package/lib/sqlBuilder.ts +358 -58
- package/lib/sqlCheck.ts +136 -0
- package/lib/validator.ts +1 -1
- package/loader/loadApis.ts +23 -126
- package/loader/loadHooks.ts +31 -46
- package/loader/loadPlugins.ts +37 -52
- package/main.ts +58 -19
- package/package.json +24 -25
- package/paths.ts +14 -14
- package/plugins/cache.ts +12 -6
- package/plugins/cipher.ts +2 -2
- package/plugins/config.ts +6 -8
- package/plugins/db.ts +14 -19
- package/plugins/jwt.ts +6 -7
- package/plugins/logger.ts +7 -9
- package/plugins/redis.ts +8 -10
- package/plugins/tool.ts +3 -4
- package/router/api.ts +3 -2
- package/router/static.ts +7 -5
- package/sync/syncApi.ts +80 -235
- package/sync/syncCache.ts +16 -0
- package/sync/syncDev.ts +167 -202
- package/sync/syncMenu.ts +230 -444
- package/sync/syncTable.ts +1247 -0
- package/tests/_mocks/mockSqliteDb.ts +204 -0
- package/tests/addonHelper-cache.test.ts +32 -0
- package/tests/apiHandler-routePath-only.test.ts +32 -0
- package/tests/cacheHelper.test.ts +16 -51
- package/tests/checkApi-routePath-strict.test.ts +166 -0
- package/tests/checkMenu.test.ts +346 -0
- package/tests/checkTable-smoke.test.ts +157 -0
- package/tests/dbDialect-cache.test.ts +23 -0
- package/tests/dbDialect.test.ts +46 -0
- package/tests/dbHelper-advanced.test.ts +1 -1
- package/tests/dbHelper-all-array-types.test.ts +15 -15
- package/tests/dbHelper-batch-write.test.ts +90 -0
- package/tests/dbHelper-columns.test.ts +36 -54
- package/tests/dbHelper-execute.test.ts +26 -26
- package/tests/dbHelper-joins.test.ts +85 -176
- package/tests/fixtures/scanFilesAddon/node_modules/@befly-addon/demo/apis/sub/b.ts +3 -0
- package/tests/fixtures/scanFilesApis/a.ts +3 -0
- package/tests/fixtures/scanFilesApis/sub/b.ts +3 -0
- package/tests/loadPlugins-order-smoke.test.ts +75 -0
- package/tests/logger.test.ts +6 -6
- package/tests/redisHelper.test.ts +6 -1
- package/tests/scanFiles-routePath.test.ts +46 -0
- package/tests/smoke-sql.test.ts +24 -0
- package/tests/sqlBuilder-advanced.test.ts +18 -5
- package/tests/sqlBuilder.test.ts +24 -0
- package/tests/sync-init-guard.test.ts +105 -0
- package/tests/syncApi-insBatch-fields-consistent.test.ts +61 -0
- package/tests/syncApi-obsolete-records.test.ts +69 -0
- package/tests/syncApi-type-compat.test.ts +72 -0
- package/tests/syncDev-permissions.test.ts +81 -0
- package/tests/syncMenu-disableMenus-hard-delete.test.ts +88 -0
- package/tests/syncMenu-duplicate-path.test.ts +122 -0
- package/tests/syncMenu-obsolete-records.test.ts +161 -0
- package/tests/syncMenu-parentPath-from-tree.test.ts +75 -0
- package/tests/syncMenu-paths.test.ts +0 -9
- package/tests/{syncDb-apply.test.ts → syncTable-apply.test.ts} +14 -24
- package/tests/{syncDb-array-number.test.ts → syncTable-array-number.test.ts} +31 -31
- package/tests/syncTable-constants.test.ts +101 -0
- package/tests/syncTable-db-integration.test.ts +237 -0
- package/tests/{syncDb-ddl.test.ts → syncTable-ddl.test.ts} +67 -53
- package/tests/{syncDb-helpers.test.ts → syncTable-helpers.test.ts} +12 -26
- package/tests/syncTable-schema.test.ts +99 -0
- package/tests/syncTable-testkit.test.ts +25 -0
- package/tests/syncTable-types.test.ts +122 -0
- package/tests/tableRef-and-deserialize.test.ts +67 -0
- package/tsconfig.json +1 -1
- package/types/api.d.ts +1 -1
- package/types/befly.d.ts +13 -12
- package/types/cache.d.ts +2 -2
- package/types/context.d.ts +1 -1
- package/types/database.d.ts +0 -5
- package/types/hook.d.ts +1 -10
- package/types/plugin.d.ts +2 -96
- package/types/sync.d.ts +19 -25
- package/utils/convertBigIntFields.ts +38 -0
- package/utils/disableMenusGlob.ts +85 -0
- package/utils/importDefault.ts +21 -0
- package/utils/isDirentDirectory.ts +23 -0
- package/utils/loadMenuConfigs.ts +145 -0
- package/utils/processFields.ts +25 -0
- package/utils/scanAddons.ts +72 -0
- package/utils/scanFiles.ts +129 -21
- package/utils/scanSources.ts +64 -0
- package/utils/sortModules.ts +137 -0
- package/checks/checkApp.ts +0 -55
- package/docs/cipher.md +0 -582
- package/docs/database.md +0 -1176
- package/hooks/rateLimit.ts +0 -276
- package/sync/syncAll.ts +0 -35
- package/sync/syncDb/apply.ts +0 -192
- package/sync/syncDb/constants.ts +0 -119
- package/sync/syncDb/ddl.ts +0 -251
- package/sync/syncDb/helpers.ts +0 -84
- package/sync/syncDb/schema.ts +0 -202
- package/sync/syncDb/sqlite.ts +0 -48
- package/sync/syncDb/table.ts +0 -207
- package/sync/syncDb/tableCreate.ts +0 -163
- package/sync/syncDb/types.ts +0 -132
- package/sync/syncDb/version.ts +0 -69
- package/sync/syncDb.ts +0 -168
- package/tests/rateLimit-hook.test.ts +0 -477
- package/tests/syncDb-constants.test.ts +0 -130
- package/tests/syncDb-schema.test.ts +0 -179
- package/tests/syncDb-types.test.ts +0 -139
- package/utils/addonHelper.ts +0 -90
- package/utils/modules.ts +0 -98
- package/utils/route.ts +0 -23
package/docs/reference/logger.md
CHANGED
|
@@ -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: "
|
|
396
|
+
Logger.warn({ config: "invalidOption" }, "配置项不合法");
|
|
397
397
|
|
|
398
398
|
// error: 操作失败
|
|
399
399
|
Logger.error({ err: error }, "数据库连接失败");
|
package/docs/reference/sync.md
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
# Sync
|
|
1
|
+
# Sync 同步流程
|
|
2
2
|
|
|
3
3
|
> 数据库结构、API路由、菜单配置、开发账户同步
|
|
4
4
|
|
|
5
5
|
## 目录
|
|
6
6
|
|
|
7
7
|
- [概述](#概述)
|
|
8
|
-
- [
|
|
9
|
-
- [
|
|
8
|
+
- [强约束清单](#强约束清单)
|
|
9
|
+
- [syncTable 数据库同步](#synctable-数据库同步)
|
|
10
10
|
- [syncApi 接口同步](#syncapi-接口同步)
|
|
11
11
|
- [syncMenu 菜单同步](#syncmenu-菜单同步)
|
|
12
12
|
- [syncDev 开发账户同步](#syncdev-开发账户同步)
|
|
13
|
-
- [
|
|
13
|
+
- [syncCache 缓存同步](#synccache-缓存同步)
|
|
14
14
|
- [表名规则](#表名规则)
|
|
15
15
|
- [注意事项](#注意事项)
|
|
16
16
|
- [FAQ](#faq)
|
|
@@ -21,103 +21,62 @@
|
|
|
21
21
|
|
|
22
22
|
Sync 同步系统用于将代码定义同步到数据库,包括:
|
|
23
23
|
|
|
24
|
-
| 命令
|
|
25
|
-
|
|
|
26
|
-
| `
|
|
27
|
-
| `syncApi`
|
|
28
|
-
| `syncMenu`
|
|
29
|
-
| `syncDev`
|
|
30
|
-
| `
|
|
24
|
+
| 命令 | 功能 | 目标表 |
|
|
25
|
+
| ----------- | ----------------- | --------------------------------------- |
|
|
26
|
+
| `syncTable` | 同步表结构定义 | 所有业务表 |
|
|
27
|
+
| `syncApi` | 同步 API 路由信息 | `addon_admin_api` |
|
|
28
|
+
| `syncMenu` | 同步菜单配置 | `addon_admin_menu` |
|
|
29
|
+
| `syncDev` | 创建开发者账户 | `addon_admin_role`, `addon_admin_admin` |
|
|
30
|
+
| `syncCache` | 同步缓存 | Redis(apis/menu/role-permissions) |
|
|
31
31
|
|
|
32
|
-
**执行顺序**:`
|
|
32
|
+
**执行顺序**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
|
|
33
33
|
|
|
34
34
|
---
|
|
35
35
|
|
|
36
|
-
##
|
|
36
|
+
## 强约束清单
|
|
37
37
|
|
|
38
|
-
|
|
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:`。
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
# 执行全量同步
|
|
42
|
-
befly sync
|
|
43
|
-
|
|
44
|
-
# 等同于依次执行:
|
|
45
|
-
# 1. checkApp - 检查应用配置
|
|
46
|
-
# 2. syncDb - 同步数据库表结构
|
|
47
|
-
# 3. syncApi - 同步 API 路由
|
|
48
|
-
# 4. syncMenu - 同步菜单配置
|
|
49
|
-
# 5. syncDev - 同步开发账户
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**执行流程**:
|
|
53
|
-
|
|
54
|
-
```
|
|
55
|
-
┌──────────────────────────────────────────────────┐
|
|
56
|
-
│ syncAll │
|
|
57
|
-
├──────────────────────────────────────────────────┤
|
|
58
|
-
│ 1. checkApp() 检查应用配置是否完整 │
|
|
59
|
-
│ ↓ │
|
|
60
|
-
│ 2. syncDbCommand() 同步数据库表结构 │
|
|
61
|
-
│ ↓ │
|
|
62
|
-
│ 3. syncApiCommand() 同步 API 路由到数据库 │
|
|
63
|
-
│ ↓ │
|
|
64
|
-
│ 4. syncMenuCommand() 同步菜单配置到数据库 │
|
|
65
|
-
│ ↓ │
|
|
66
|
-
│ 5. syncDevCommand() 创建/更新开发者账户 │
|
|
67
|
-
└──────────────────────────────────────────────────┘
|
|
68
|
-
```
|
|
43
|
+
> 说明:当前版本不提供 CLI 同步命令;同步逻辑在服务启动时由主进程自动执行(见 `packages/core/main.ts`)。
|
|
69
44
|
|
|
70
45
|
---
|
|
71
46
|
|
|
72
|
-
##
|
|
47
|
+
## syncTable 数据库同步
|
|
73
48
|
|
|
74
49
|
将 `tables/*.json` 表定义同步到数据库结构。
|
|
75
50
|
|
|
76
51
|
### 基本用法
|
|
77
52
|
|
|
78
|
-
|
|
79
|
-
# 同步所有表
|
|
80
|
-
befly sync:db
|
|
53
|
+
默认会在服务启动时自动执行(仅主进程)。如需在代码中手动执行:
|
|
81
54
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# 强制模式(允许破坏性操作)
|
|
86
|
-
befly sync:db --force
|
|
55
|
+
```typescript
|
|
56
|
+
import { syncTable } from "../sync/syncTable.js";
|
|
57
|
+
import { scanSources } from "../utils/scanSources.js";
|
|
87
58
|
|
|
88
|
-
|
|
89
|
-
|
|
59
|
+
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
|
|
60
|
+
const sources = await scanSources();
|
|
61
|
+
await syncTable(ctx, sources.tables);
|
|
90
62
|
```
|
|
91
63
|
|
|
92
64
|
### 命令选项
|
|
93
65
|
|
|
94
|
-
|
|
95
|
-
| ----------- | ------- | ------ | -------------------- |
|
|
96
|
-
| `--table` | string | - | 只同步指定表 |
|
|
97
|
-
| `--force` | boolean | false | 强制模式,允许删除列 |
|
|
98
|
-
| `--dry-run` | boolean | false | 预览模式,不实际执行 |
|
|
66
|
+
无
|
|
99
67
|
|
|
100
68
|
### 同步逻辑
|
|
101
69
|
|
|
102
70
|
```
|
|
103
71
|
┌─────────────────────────────────────────────────────┐
|
|
104
|
-
│
|
|
72
|
+
│ syncTable │
|
|
105
73
|
├─────────────────────────────────────────────────────┤
|
|
106
|
-
│ 1.
|
|
107
|
-
│ 2.
|
|
108
|
-
│ 3.
|
|
109
|
-
│ 4. 确保版本表存在 (ensureDbVersion) │
|
|
110
|
-
│ ↓ │
|
|
111
|
-
│ 5. 扫描表定义文件: │
|
|
112
|
-
│ - 项目表:tpl/tables/*.json │
|
|
113
|
-
│ - Addon 表:addons/*/tables/*.json │
|
|
114
|
-
│ ↓ │
|
|
115
|
-
│ 6. 对每个表: │
|
|
74
|
+
│ 1. 校验 ctx.db / ctx.redis / ctx.config │
|
|
75
|
+
│ 2. 检查数据库版本 (ensureDbVersion) │
|
|
76
|
+
│ 3. 同步传入的表定义列表(通常来自 scanSources) │
|
|
116
77
|
│ ├── 表存在?→ modifyTable (修改) │
|
|
117
78
|
│ └── 表不存在?→ createTable (新建) │
|
|
118
|
-
│
|
|
119
|
-
│ 7. 清理 Redis 缓存 (tableColumns) │
|
|
120
|
-
│ 8. 关闭数据库连接 │
|
|
79
|
+
│ 4. 清理 Redis 缓存 (tableColumns) │
|
|
121
80
|
└─────────────────────────────────────────────────────┘
|
|
122
81
|
```
|
|
123
82
|
|
|
@@ -156,19 +115,17 @@ befly sync:db --dry-run
|
|
|
156
115
|
|
|
157
116
|
### 基本用法
|
|
158
117
|
|
|
159
|
-
|
|
160
|
-
# 同步 API 路由
|
|
161
|
-
befly sync:api
|
|
118
|
+
通常无需单独调用:服务启动流程会按顺序执行 `syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`。
|
|
162
119
|
|
|
163
|
-
|
|
164
|
-
befly sync:api --plan
|
|
165
|
-
```
|
|
120
|
+
如需在代码中手动调用:
|
|
166
121
|
|
|
167
|
-
|
|
122
|
+
```typescript
|
|
123
|
+
import { syncApi } from "../sync/syncApi.js";
|
|
124
|
+
import { scanSources } from "../utils/scanSources.js";
|
|
168
125
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
126
|
+
const sources = await scanSources();
|
|
127
|
+
await syncApi(ctx, sources.apis as any);
|
|
128
|
+
```
|
|
172
129
|
|
|
173
130
|
### 同步逻辑
|
|
174
131
|
|
|
@@ -194,20 +151,15 @@ befly sync:api --plan
|
|
|
194
151
|
└─────────────────────────────────────────────────────┘
|
|
195
152
|
```
|
|
196
153
|
|
|
197
|
-
###
|
|
154
|
+
### 存储字段(重要)
|
|
198
155
|
|
|
199
|
-
|
|
156
|
+
`syncApi` 会把扫描到的 API 信息同步到 `addon_admin_api` 表,核心字段为:
|
|
200
157
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
description: string; // 接口描述(desc 属性)
|
|
207
|
-
addonName: string; // 所属 Addon 名称
|
|
208
|
-
addonTitle: string; // Addon 标题
|
|
209
|
-
}
|
|
210
|
-
```
|
|
158
|
+
- `routePath`:只存 `url.pathname`(例如 `/api/user/login`),与 method 无关
|
|
159
|
+
- `name`:接口名称
|
|
160
|
+
- `addonName`:所属 addon(无 addon 时为空字符串)
|
|
161
|
+
|
|
162
|
+
> 注意:`routePath` 必须是 pathname(以 `/` 开头),不允许写成 `POST /api/...` 或 `POST/api/...`。
|
|
211
163
|
|
|
212
164
|
### 统计信息
|
|
213
165
|
|
|
@@ -228,19 +180,19 @@ interface SyncApiStats {
|
|
|
228
180
|
|
|
229
181
|
### 基本用法
|
|
230
182
|
|
|
231
|
-
|
|
232
|
-
# 同步菜单
|
|
233
|
-
befly sync:menu
|
|
183
|
+
同 `syncApi`,通常由启动流程统一触发。
|
|
234
184
|
|
|
235
|
-
|
|
236
|
-
befly sync:menu --plan
|
|
237
|
-
```
|
|
185
|
+
如需手动调用,需要先对菜单配置做校验/过滤(例如 disableMenus):
|
|
238
186
|
|
|
239
|
-
|
|
187
|
+
```typescript
|
|
188
|
+
import { checkMenu } from "../checks/checkMenu.js";
|
|
189
|
+
import { syncMenu } from "../sync/syncMenu.js";
|
|
190
|
+
import { scanSources } from "../utils/scanSources.js";
|
|
240
191
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
192
|
+
const sources = await scanSources();
|
|
193
|
+
const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
|
|
194
|
+
await syncMenu(ctx, checkedMenus);
|
|
195
|
+
```
|
|
244
196
|
|
|
245
197
|
### 菜单配置文件
|
|
246
198
|
|
|
@@ -325,104 +277,80 @@ interface SyncMenuStats {
|
|
|
325
277
|
|
|
326
278
|
### 基本用法
|
|
327
279
|
|
|
328
|
-
|
|
329
|
-
# 同步开发账户
|
|
330
|
-
befly sync:dev
|
|
331
|
-
|
|
332
|
-
# 预览模式
|
|
333
|
-
befly sync:dev --plan
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### 命令选项
|
|
337
|
-
|
|
338
|
-
| 选项 | 类型 | 默认值 | 说明 |
|
|
339
|
-
| -------- | ------- | ------ | ---------------------- |
|
|
340
|
-
| `--plan` | boolean | false | 预览模式,显示变更计划 |
|
|
280
|
+
同 `syncApi`,通常由启动流程统一触发。
|
|
341
281
|
|
|
342
282
|
### 同步逻辑
|
|
343
283
|
|
|
344
284
|
```
|
|
345
285
|
┌─────────────────────────────────────────────────────┐
|
|
346
|
-
│
|
|
286
|
+
│ syncDev │
|
|
347
287
|
├─────────────────────────────────────────────────────┤
|
|
348
|
-
│
|
|
349
|
-
│
|
|
350
|
-
│
|
|
351
|
-
│
|
|
352
|
-
│
|
|
353
|
-
│
|
|
354
|
-
│
|
|
355
|
-
│
|
|
356
|
-
│
|
|
357
|
-
│
|
|
358
|
-
│
|
|
359
|
-
│
|
|
360
|
-
│
|
|
361
|
-
│
|
|
362
|
-
│
|
|
363
|
-
│
|
|
364
|
-
│
|
|
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
|
+
│ - 角色:开发者角色 │
|
|
365
305
|
└─────────────────────────────────────────────────────┘
|
|
366
306
|
```
|
|
367
307
|
|
|
368
308
|
### 配置说明
|
|
369
309
|
|
|
370
|
-
开发账户配置在 `befly.config.ts`
|
|
310
|
+
开发账户配置在 `befly.config.ts` 或环境配置文件中(仅当 `devPassword` 有值时才会创建 dev 账号):
|
|
371
311
|
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
password: "dev123456" // 开发账户密码
|
|
378
|
-
}
|
|
379
|
-
};
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"devEmail": "dev@qq.com",
|
|
315
|
+
"devPassword": "beflydev123456"
|
|
316
|
+
}
|
|
380
317
|
```
|
|
381
318
|
|
|
382
|
-
|
|
319
|
+
> 注意:`syncDev` 会把 `menus/apis` 写入角色表,并且 `apis` 必须是 pathname 字符串数组(严格模式下不允许 numeric id)。
|
|
383
320
|
|
|
384
321
|
---
|
|
385
322
|
|
|
386
|
-
##
|
|
323
|
+
## syncCache 缓存同步
|
|
387
324
|
|
|
388
|
-
|
|
325
|
+
同步缓存(统一收敛到启动流程末尾执行):
|
|
389
326
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
327
|
+
- `cacheApis()`:缓存接口列表
|
|
328
|
+
- `cacheMenus()`:缓存菜单列表
|
|
329
|
+
- `rebuildRoleApiPermissions()`:重建角色接口权限 Set(member 为 pathname,与 method 无关)
|
|
393
330
|
|
|
394
|
-
|
|
395
|
-
befly sync:db # 同步数据库结构
|
|
396
|
-
befly sync:api # 同步 API 路由
|
|
397
|
-
befly sync:menu # 同步菜单配置
|
|
398
|
-
befly sync:dev # 同步开发账户
|
|
399
|
-
|
|
400
|
-
# 带参数
|
|
401
|
-
befly sync:db --table user # 只同步 user 表
|
|
402
|
-
befly sync:db --force # 强制模式
|
|
403
|
-
befly sync:db --dry-run # 预览模式
|
|
404
|
-
befly sync:api --plan # 预览 API 变更
|
|
405
|
-
befly sync:menu --plan # 预览菜单变更
|
|
406
|
-
befly sync:dev --plan # 预览开发账户变更
|
|
407
|
-
```
|
|
331
|
+
---
|
|
408
332
|
|
|
409
|
-
|
|
333
|
+
## 代码调用
|
|
410
334
|
|
|
411
335
|
```typescript
|
|
412
|
-
import {
|
|
413
|
-
import {
|
|
414
|
-
import {
|
|
415
|
-
import {
|
|
416
|
-
import {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
//
|
|
422
|
-
|
|
423
|
-
await
|
|
424
|
-
|
|
425
|
-
await
|
|
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";
|
|
341
|
+
import { scanSources } from "./utils/scanSources.js";
|
|
342
|
+
import { checkMenu } from "./checks/checkMenu.js";
|
|
343
|
+
|
|
344
|
+
// 启动前/启动中手动触发同步
|
|
345
|
+
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.cache / ctx.config)
|
|
346
|
+
const sources = await scanSources();
|
|
347
|
+
const checkedMenus = await checkMenu(sources.addons, { disableMenus: ctx.config.disableMenus || [] });
|
|
348
|
+
|
|
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);
|
|
426
354
|
```
|
|
427
355
|
|
|
428
356
|
---
|
|
@@ -464,29 +392,27 @@ addons/demo/tables/article.json → addon_demo_article
|
|
|
464
392
|
|
|
465
393
|
### 1. 执行顺序
|
|
466
394
|
|
|
467
|
-
**必须按顺序执行**:`
|
|
395
|
+
**必须按顺序执行**:`syncTable` → `syncApi` → `syncMenu` → `syncDev` → `syncCache`
|
|
468
396
|
|
|
469
|
-
- `syncApi` 依赖 `addon_admin_api` 表(由 `
|
|
470
|
-
- `syncMenu` 依赖 `addon_admin_menu` 表(由 `
|
|
397
|
+
- `syncApi` 依赖 `addon_admin_api` 表(由 `syncTable` 创建)
|
|
398
|
+
- `syncMenu` 依赖 `addon_admin_menu` 表(由 `syncTable` 创建)
|
|
471
399
|
- `syncDev` 依赖角色表和权限数据(由前面命令创建)
|
|
472
400
|
|
|
473
401
|
### 2. 破坏性操作
|
|
474
402
|
|
|
475
|
-
默认模式下,`
|
|
403
|
+
默认模式下,`syncTable` **不会删除列**,只会:
|
|
476
404
|
|
|
477
405
|
- 新增缺失的列
|
|
478
406
|
- 修改现有列的类型/默认值
|
|
479
407
|
|
|
480
|
-
|
|
408
|
+
此外,`syncTable` **不会执行长度收缩等可能导致数据截断的危险变更**:
|
|
481
409
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
befly sync:db --force
|
|
485
|
-
```
|
|
410
|
+
- 例如:`VARCHAR(200)` → `VARCHAR(50)`
|
|
411
|
+
- 这类变更会被跳过,并输出告警;需要手动评估并处理
|
|
486
412
|
|
|
487
413
|
### 3. 缓存清理
|
|
488
414
|
|
|
489
|
-
`
|
|
415
|
+
`syncTable` 执行后会自动清理 Redis 中的表结构缓存:
|
|
490
416
|
|
|
491
417
|
```typescript
|
|
492
418
|
// 自动清理以下缓存键
|
|
@@ -495,21 +421,10 @@ CacheKeys.tableColumns(tableName); // table:columns:{tableName}
|
|
|
495
421
|
|
|
496
422
|
### 4. 连接管理
|
|
497
423
|
|
|
498
|
-
|
|
424
|
+
`sync*` 函数本身不会负责建立连接/加载插件:
|
|
499
425
|
|
|
500
|
-
-
|
|
501
|
-
-
|
|
502
|
-
- 出错时正确清理资源
|
|
503
|
-
|
|
504
|
-
### 5. 预览模式
|
|
505
|
-
|
|
506
|
-
使用 `--dry-run` 或 `--plan` 参数可以预览变更而不实际执行:
|
|
507
|
-
|
|
508
|
-
```bash
|
|
509
|
-
befly sync:db --dry-run # 预览数据库结构变更
|
|
510
|
-
befly sync:api --plan # 预览 API 变更
|
|
511
|
-
befly sync:menu --plan # 预览菜单变更
|
|
512
|
-
```
|
|
426
|
+
- 你需要在调用前确保 `Connect.connect(...)` 已执行,并且 `Db/Redis/cache` 插件已注入到 `ctx`。
|
|
427
|
+
- 服务启动流程已内置这套顺序(见 `packages/core/main.ts`)。
|
|
513
428
|
|
|
514
429
|
---
|
|
515
430
|
|
|
@@ -517,7 +432,7 @@ befly sync:menu --plan # 预览菜单变更
|
|
|
517
432
|
|
|
518
433
|
### Q: sync 命令报错 "表不存在" 怎么办?
|
|
519
434
|
|
|
520
|
-
A:
|
|
435
|
+
A: 确保 `syncTable()` 已先执行(服务启动时会自动执行)。`syncApi/syncMenu/syncDev` 依赖对应的表结构存在。
|
|
521
436
|
|
|
522
437
|
### Q: 为什么修改了表定义但数据库没变化?
|
|
523
438
|
|
|
@@ -526,17 +441,11 @@ A: 检查以下几点:
|
|
|
526
441
|
1. JSON 文件语法是否正确
|
|
527
442
|
2. 字段定义格式是否正确
|
|
528
443
|
3. 是否保存了文件
|
|
529
|
-
4.
|
|
530
|
-
|
|
531
|
-
### Q: 如何删除数据库中不需要的列?
|
|
444
|
+
4. 确认表定义文件与配置已保存
|
|
532
445
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
```bash
|
|
536
|
-
befly sync:db --force
|
|
537
|
-
```
|
|
446
|
+
### Q: 如何处理“字段长度收缩”这类危险变更?
|
|
538
447
|
|
|
539
|
-
|
|
448
|
+
A: `syncTable()` 会跳过长度收缩并告警;请手动评估并处理(例如先清理/截断数据,再手动执行 DDL),再重新启动服务或再次调用 `syncTable()`。
|
|
540
449
|
|
|
541
450
|
### Q: Addon 表名太长怎么办?
|
|
542
451
|
|
|
@@ -550,34 +459,20 @@ A: Addon 表名格式为 `addon_{addonName}_{tableName}`,建议:
|
|
|
550
459
|
|
|
551
460
|
A:
|
|
552
461
|
|
|
553
|
-
1.
|
|
554
|
-
2.
|
|
555
|
-
3. sync 命令是幂等的,可以安全地多次执行
|
|
462
|
+
1. 检查错误日志确定失败原因(例如表不存在、字段变更被跳过等)
|
|
463
|
+
2. sync 命令是幂等的,可以安全地多次执行
|
|
556
464
|
|
|
557
465
|
### Q: 如何只同步某个 Addon 的表?
|
|
558
466
|
|
|
559
|
-
A:
|
|
560
|
-
|
|
561
|
-
```bash
|
|
562
|
-
befly sync:db --table addon_admin_role
|
|
563
|
-
```
|
|
467
|
+
A: 当前不支持按 Addon 或单表筛选;会同步项目与所有 Addon 的表定义。
|
|
564
468
|
|
|
565
469
|
### Q: 开发账户密码在哪里配置?
|
|
566
470
|
|
|
567
|
-
A:
|
|
568
|
-
|
|
569
|
-
```typescript
|
|
570
|
-
// befly.config.ts
|
|
571
|
-
export default {
|
|
572
|
-
dev: {
|
|
573
|
-
username: "dev",
|
|
574
|
-
password: "your_password"
|
|
575
|
-
}
|
|
576
|
-
};
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
或使用环境变量:
|
|
471
|
+
A: 在配置文件中设置(仅当 `devPassword` 有值时才会创建 dev 账号):
|
|
580
472
|
|
|
581
|
-
```
|
|
582
|
-
|
|
473
|
+
```json
|
|
474
|
+
{
|
|
475
|
+
"devEmail": "dev@qq.com",
|
|
476
|
+
"devPassword": "beflydev123456"
|
|
477
|
+
}
|
|
583
478
|
```
|
package/docs/reference/table.md
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
- [字段名规范](#字段名规范)
|
|
38
38
|
- [类型联动校验](#类型联动校验)
|
|
39
39
|
- [数据库同步](#数据库同步)
|
|
40
|
-
- [
|
|
40
|
+
- [触发方式](#触发方式)
|
|
41
41
|
- [同步流程](#同步流程)
|
|
42
42
|
- [变更检测](#变更检测)
|
|
43
43
|
- [安全机制](#安全机制)
|
|
@@ -429,13 +429,13 @@ interface FieldDefinition {
|
|
|
429
429
|
|
|
430
430
|
以下字段由系统自动创建和管理,**不能**在表定义中使用:
|
|
431
431
|
|
|
432
|
-
| 字段名 | 类型
|
|
433
|
-
| ------------ |
|
|
434
|
-
| `id` | `BIGINT`
|
|
435
|
-
| `created_at` | `BIGINT`
|
|
436
|
-
| `updated_at` | `BIGINT`
|
|
437
|
-
| `deleted_at` | `BIGINT`
|
|
438
|
-
| `state` | `
|
|
432
|
+
| 字段名 | 类型 | 说明 |
|
|
433
|
+
| ------------ | -------- | ------------------------ |
|
|
434
|
+
| `id` | `BIGINT` | 主键 ID,自增 |
|
|
435
|
+
| `created_at` | `BIGINT` | 创建时间戳(毫秒) |
|
|
436
|
+
| `updated_at` | `BIGINT` | 更新时间戳(毫秒) |
|
|
437
|
+
| `deleted_at` | `BIGINT` | 删除时间戳(软删除标记) |
|
|
438
|
+
| `state` | `BIGINT` | 状态字段 |
|
|
439
439
|
|
|
440
440
|
**系统自动创建的索引:**
|
|
441
441
|
|
|
@@ -510,20 +510,19 @@ interface FieldDefinition {
|
|
|
510
510
|
|
|
511
511
|
## 数据库同步
|
|
512
512
|
|
|
513
|
-
###
|
|
513
|
+
### 触发方式
|
|
514
514
|
|
|
515
|
-
|
|
516
|
-
# 同步所有表
|
|
517
|
-
bun run sync:db
|
|
515
|
+
服务启动时会在**主进程**自动执行 `syncTable()`。
|
|
518
516
|
|
|
519
|
-
|
|
520
|
-
bun run sync:db --table=user
|
|
517
|
+
如需在代码中手动触发:
|
|
521
518
|
|
|
522
|
-
|
|
523
|
-
|
|
519
|
+
```typescript
|
|
520
|
+
import { syncTable } from "../../sync/syncTable.js";
|
|
521
|
+
import { scanSources } from "../../utils/scanSources.js";
|
|
524
522
|
|
|
525
|
-
|
|
526
|
-
|
|
523
|
+
// ctx:BeflyContext(需已具备 ctx.db / ctx.redis / ctx.config)
|
|
524
|
+
const sources = await scanSources();
|
|
525
|
+
await syncTable(ctx, sources.tables);
|
|
527
526
|
```
|
|
528
527
|
|
|
529
528
|
### 同步流程
|
|
@@ -556,22 +555,21 @@ bun run sync:db --force
|
|
|
556
555
|
|
|
557
556
|
同步时检测以下变更:
|
|
558
557
|
|
|
559
|
-
| 变更类型 | 说明 | 自动执行
|
|
560
|
-
| -------- | ---------------------------- |
|
|
561
|
-
| 长度扩展 | VARCHAR 长度增加 | ✓
|
|
562
|
-
| 长度收缩 | VARCHAR 长度减少 |
|
|
563
|
-
| 类型宽化 | INT → BIGINT, VARCHAR → TEXT | ✓
|
|
564
|
-
| 类型变更 | 其他类型变更 | ✗ 禁止
|
|
565
|
-
| 默认值 | 默认值变更 | ✓
|
|
566
|
-
| 注释 | 字段注释变更 | ✓
|
|
567
|
-
| 索引 | 添加/删除索引 | ✓
|
|
558
|
+
| 变更类型 | 说明 | 自动执行 |
|
|
559
|
+
| -------- | ---------------------------- | -------------------- |
|
|
560
|
+
| 长度扩展 | VARCHAR 长度增加 | ✓ |
|
|
561
|
+
| 长度收缩 | VARCHAR 长度减少 | ✗ 跳过(需手动处理) |
|
|
562
|
+
| 类型宽化 | INT → BIGINT, VARCHAR → TEXT | ✓ |
|
|
563
|
+
| 类型变更 | 其他类型变更 | ✗ 禁止 |
|
|
564
|
+
| 默认值 | 默认值变更 | ✓ |
|
|
565
|
+
| 注释 | 字段注释变更 | ✓ |
|
|
566
|
+
| 索引 | 添加/删除索引 | ✓ |
|
|
568
567
|
|
|
569
568
|
### 安全机制
|
|
570
569
|
|
|
571
|
-
1. **禁止危险类型变更**:不允许从 `BIGINT` 改为 `VARCHAR`
|
|
570
|
+
1. **禁止危险类型变更**:不允许从 `BIGINT` 改为 `VARCHAR` 等高风险变更
|
|
572
571
|
2. **长度收缩保护**:默认跳过长度收缩,避免数据截断
|
|
573
|
-
3.
|
|
574
|
-
4. **保留字段保护**:不允许定义系统保留字段
|
|
572
|
+
3. **保留字段保护**:不允许定义系统保留字段
|
|
575
573
|
|
|
576
574
|
---
|
|
577
575
|
|
package/hooks/auth.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { Hook } from "../types/hook.js";
|
|
|
2
2
|
|
|
3
3
|
import { setCtxUser } from "../lib/asyncContext.js";
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
export default {
|
|
6
|
+
deps: ["cors"],
|
|
7
7
|
handler: async (befly, ctx) => {
|
|
8
8
|
const authHeader = ctx.req.headers.get("authorization");
|
|
9
9
|
|
|
@@ -22,5 +22,4 @@ const hook: Hook = {
|
|
|
22
22
|
ctx.user = {};
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
};
|
|
26
|
-
export default hook;
|
|
25
|
+
} satisfies Hook;
|