befly 3.8.30 → 3.8.31
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 +83 -0
- package/checks/checkApp.ts +31 -1
- package/hooks/cors.ts +3 -3
- package/hooks/parser.ts +3 -3
- package/hooks/validator.ts +1 -1
- package/lib/cacheHelper.ts +0 -6
- package/lib/cipher.ts +2 -1
- package/lib/connect.ts +17 -19
- package/lib/jwt.ts +1 -1
- package/lib/logger.ts +1 -1
- package/lib/validator.ts +149 -384
- package/loader/loadHooks.ts +4 -3
- package/loader/loadPlugins.ts +7 -9
- package/main.ts +22 -36
- package/package.json +4 -3
- package/plugins/cipher.ts +1 -1
- package/plugins/config.ts +3 -4
- package/plugins/db.ts +4 -5
- package/plugins/jwt.ts +3 -2
- package/plugins/logger.ts +6 -6
- package/plugins/redis.ts +8 -12
- package/router/static.ts +3 -6
- package/sync/syncAll.ts +7 -12
- package/sync/syncApi.ts +4 -3
- package/sync/syncDb.ts +6 -5
- package/sync/syncDev.ts +9 -8
- package/sync/syncMenu.ts +174 -132
- package/tests/integration.test.ts +2 -6
- package/tests/redisHelper.test.ts +1 -2
- package/tests/validator.test.ts +611 -85
- package/types/befly.d.ts +7 -0
- package/types/cache.d.ts +73 -0
- package/types/common.d.ts +1 -37
- package/types/database.d.ts +5 -0
- package/types/index.ts +5 -5
- package/types/plugin.d.ts +1 -4
- package/types/redis.d.ts +37 -2
- package/types/table.d.ts +6 -44
- package/config.ts +0 -70
- package/tests/validator-advanced.test.ts +0 -653
- package/types/addon.d.ts +0 -50
- package/types/crypto.d.ts +0 -23
- package/types/jwt.d.ts +0 -99
- package/types/logger.d.ts +0 -13
- package/types/tool.d.ts +0 -67
- package/types/validator.d.ts +0 -43
package/loader/loadPlugins.ts
CHANGED
|
@@ -8,28 +8,29 @@ import { scanAddons, getAddonDir } from 'befly-shared/addonHelper';
|
|
|
8
8
|
import { Logger } from '../lib/logger.js';
|
|
9
9
|
import { corePluginDir, projectPluginDir } from '../paths.js';
|
|
10
10
|
import { sortModules, scanModules } from '../util.js';
|
|
11
|
+
import { beflyConfig } from '../befly.config.js';
|
|
11
12
|
|
|
12
13
|
import type { Plugin } from '../types/plugin.js';
|
|
13
14
|
import type { BeflyContext } from '../types/befly.js';
|
|
14
15
|
|
|
15
|
-
export async function loadPlugins(
|
|
16
|
+
export async function loadPlugins(plugins: Plugin[], context: BeflyContext): Promise<void> {
|
|
16
17
|
try {
|
|
17
18
|
const allPlugins: Plugin[] = [];
|
|
18
19
|
|
|
19
20
|
// 1. 扫描核心插件
|
|
20
|
-
const corePlugins = await scanModules<Plugin>(corePluginDir, 'core', '插件'
|
|
21
|
+
const corePlugins = await scanModules<Plugin>(corePluginDir, 'core', '插件');
|
|
21
22
|
|
|
22
23
|
// 2. 扫描组件插件
|
|
23
24
|
const addonPlugins: Plugin[] = [];
|
|
24
25
|
const addons = scanAddons();
|
|
25
26
|
for (const addon of addons) {
|
|
26
27
|
const dir = getAddonDir(addon, 'plugins');
|
|
27
|
-
const plugins = await scanModules<Plugin>(dir, 'addon', '插件',
|
|
28
|
+
const plugins = await scanModules<Plugin>(dir, 'addon', '插件', addon);
|
|
28
29
|
addonPlugins.push(...plugins);
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// 3. 扫描项目插件
|
|
32
|
-
const appPlugins = await scanModules<Plugin>(projectPluginDir, 'app', '插件'
|
|
33
|
+
const appPlugins = await scanModules<Plugin>(projectPluginDir, 'app', '插件');
|
|
33
34
|
|
|
34
35
|
// 4. 合并所有插件
|
|
35
36
|
allPlugins.push(...corePlugins);
|
|
@@ -37,7 +38,7 @@ export async function loadPlugins(config: Record<string, any> | undefined, plugi
|
|
|
37
38
|
allPlugins.push(...appPlugins);
|
|
38
39
|
|
|
39
40
|
// 5. 过滤禁用的插件
|
|
40
|
-
const disablePlugins =
|
|
41
|
+
const disablePlugins = beflyConfig.disablePlugins || [];
|
|
41
42
|
const enabledPlugins = allPlugins.filter((plugin) => !disablePlugins.includes(plugin.name));
|
|
42
43
|
|
|
43
44
|
if (disablePlugins.length > 0) {
|
|
@@ -55,7 +56,7 @@ export async function loadPlugins(config: Record<string, any> | undefined, plugi
|
|
|
55
56
|
try {
|
|
56
57
|
plugins.push(plugin);
|
|
57
58
|
|
|
58
|
-
const pluginInstance = typeof plugin.handler === 'function' ? await plugin.handler(context
|
|
59
|
+
const pluginInstance = typeof plugin.handler === 'function' ? await plugin.handler(context) : {};
|
|
59
60
|
|
|
60
61
|
// 直接挂载到 befly 下
|
|
61
62
|
(context as any)[plugin.name!] = pluginInstance;
|
|
@@ -69,6 +70,3 @@ export async function loadPlugins(config: Record<string, any> | undefined, plugi
|
|
|
69
70
|
process.exit(1);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
// ==================== 钩子加载逻辑 ====================
|
|
74
|
-
// 已移动到 loadHooks.ts
|
package/main.ts
CHANGED
|
@@ -8,10 +8,7 @@ import { calcPerfTime } from 'befly-shared/calcPerfTime';
|
|
|
8
8
|
|
|
9
9
|
// ========== 相对导入 ==========
|
|
10
10
|
import { Logger } from './lib/logger.js';
|
|
11
|
-
import { Cipher } from './lib/cipher.js';
|
|
12
11
|
import { Connect } from './lib/connect.js';
|
|
13
|
-
import { DbHelper } from './lib/dbHelper.js';
|
|
14
|
-
import { RedisHelper } from './lib/redisHelper.js';
|
|
15
12
|
import { loadPlugins } from './loader/loadPlugins.js';
|
|
16
13
|
import { loadHooks } from './loader/loadHooks.js';
|
|
17
14
|
import { loadApis } from './loader/loadApis.js';
|
|
@@ -21,8 +18,6 @@ import { checkApp } from './checks/checkApp.js';
|
|
|
21
18
|
import { checkTable } from './checks/checkTable.js';
|
|
22
19
|
import { checkApi } from './checks/checkApi.js';
|
|
23
20
|
import { syncAllCommand } from './sync/syncAll.js';
|
|
24
|
-
import { coreDir } from './paths.js';
|
|
25
|
-
import { defaultOptions } from './config.js';
|
|
26
21
|
import { isPrimaryProcess, getProcessRole } from './util.js';
|
|
27
22
|
|
|
28
23
|
// ========== 类型导入 ==========
|
|
@@ -31,6 +26,7 @@ import type { BeflyContext, BeflyOptions } from './types/befly.js';
|
|
|
31
26
|
import type { Plugin } from './types/plugin.js';
|
|
32
27
|
import type { Hook } from './types/hook.js';
|
|
33
28
|
import type { ApiRoute } from './types/api.js';
|
|
29
|
+
|
|
34
30
|
/**
|
|
35
31
|
* Befly 框架核心类
|
|
36
32
|
* 职责:管理应用上下文和生命周期
|
|
@@ -48,22 +44,8 @@ export class Befly {
|
|
|
48
44
|
/** 应用上下文 */
|
|
49
45
|
public context: BeflyContext = {};
|
|
50
46
|
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
constructor(options: BeflyOptions = {}) {
|
|
55
|
-
// 合并用户配置:用户配置 > 默认配置(最多 2 级)
|
|
56
|
-
for (const key in options) {
|
|
57
|
-
const value = options[key as keyof BeflyOptions];
|
|
58
|
-
if (value !== undefined && value !== null) {
|
|
59
|
-
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
60
|
-
this.config[key as keyof BeflyOptions] = { ...defaultOptions[key as keyof typeof defaultOptions], ...value } as any;
|
|
61
|
-
} else {
|
|
62
|
-
this.config[key as keyof BeflyOptions] = value as any;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
47
|
+
/** 配置引用(延迟加载) */
|
|
48
|
+
private config: BeflyOptions | null = null;
|
|
67
49
|
|
|
68
50
|
/**
|
|
69
51
|
* 启动完整的生命周期流程
|
|
@@ -73,33 +55,37 @@ export class Befly {
|
|
|
73
55
|
try {
|
|
74
56
|
const serverStartTime = Bun.nanoseconds();
|
|
75
57
|
|
|
58
|
+
// 0. 延迟加载配置(避免循环依赖)
|
|
59
|
+
const { beflyConfig } = await import('./befly.config.js');
|
|
60
|
+
this.config = beflyConfig;
|
|
61
|
+
|
|
76
62
|
// 1. 执行启动检查
|
|
77
63
|
await checkApp();
|
|
78
64
|
await checkTable();
|
|
79
65
|
await checkApi();
|
|
80
66
|
|
|
81
|
-
//
|
|
82
|
-
await loadPlugins(this.
|
|
67
|
+
// 2. 加载插件
|
|
68
|
+
await loadPlugins(this.plugins, this.context);
|
|
83
69
|
|
|
84
|
-
//
|
|
85
|
-
await loadHooks(this.
|
|
70
|
+
// 3. 加载钩子
|
|
71
|
+
await loadHooks(this.hooks);
|
|
86
72
|
|
|
87
|
-
//
|
|
73
|
+
// 4. 加载所有 API
|
|
88
74
|
await loadApis(this.apis);
|
|
89
75
|
|
|
90
|
-
//
|
|
76
|
+
// 5. 自动同步 (仅主进程执行,避免集群模式下重复执行)
|
|
91
77
|
if (isPrimaryProcess()) {
|
|
92
|
-
await syncAllCommand(
|
|
78
|
+
await syncAllCommand();
|
|
93
79
|
}
|
|
94
80
|
|
|
95
|
-
//
|
|
81
|
+
// 6. 启动 HTTP 服务器
|
|
96
82
|
const server = Bun.serve({
|
|
97
|
-
port: this.config
|
|
98
|
-
hostname: this.config
|
|
83
|
+
port: this.config!.appPort,
|
|
84
|
+
hostname: this.config!.appHost,
|
|
99
85
|
routes: {
|
|
100
|
-
'/': () => Response.json({ code: 0, msg: `${this.config
|
|
86
|
+
'/': () => Response.json({ code: 0, msg: `${this.config!.appName} 接口服务已启动` }),
|
|
101
87
|
'/api/*': apiHandler(this.apis, this.hooks, this.context),
|
|
102
|
-
'/*': staticHandler(
|
|
88
|
+
'/*': staticHandler()
|
|
103
89
|
},
|
|
104
90
|
error: (error: Error) => {
|
|
105
91
|
Logger.error({ err: error }, '服务启动时发生错误');
|
|
@@ -112,11 +98,11 @@ export class Befly {
|
|
|
112
98
|
const roleLabel = processRole.role === 'primary' ? '主进程' : `工作进程 #${processRole.instanceId}`;
|
|
113
99
|
const envLabel = processRole.env === 'standalone' ? '' : ` [${processRole.env}]`;
|
|
114
100
|
|
|
115
|
-
Logger.info(`${this.config
|
|
101
|
+
Logger.info(`${this.config!.appName} 启动成功! (${roleLabel}${envLabel})`);
|
|
116
102
|
Logger.info(`服务器启动耗时: ${finalStartupTime}`);
|
|
117
|
-
Logger.info(`服务器监听地址: http://${this.config
|
|
103
|
+
Logger.info(`服务器监听地址: http://${this.config!.appHost}:${this.config!.appPort}`);
|
|
118
104
|
|
|
119
|
-
//
|
|
105
|
+
// 7. 注册优雅关闭处理
|
|
120
106
|
const gracefulShutdown = async (signal: string) => {
|
|
121
107
|
// 停止接收新请求
|
|
122
108
|
server.stop(true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.31",
|
|
4
4
|
"description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"./*": "./*"
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
|
+
"test": "bun test",
|
|
21
22
|
"bundler": "bun build ./main.ts --outfile ./main.single.ts --minify --target bun"
|
|
22
23
|
},
|
|
23
24
|
"keywords": [
|
|
@@ -63,7 +64,7 @@
|
|
|
63
64
|
"bun": ">=1.3.0"
|
|
64
65
|
},
|
|
65
66
|
"dependencies": {
|
|
66
|
-
"befly-shared": "^1.1.
|
|
67
|
+
"befly-shared": "^1.1.2",
|
|
67
68
|
"chalk": "^5.6.2",
|
|
68
69
|
"es-toolkit": "^1.42.0",
|
|
69
70
|
"fast-jwt": "^6.0.2",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"pino": "^10.1.0",
|
|
73
74
|
"pino-roll": "^4.0.0"
|
|
74
75
|
},
|
|
75
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "d9a4c57539f6eb692d7db6c7fd800e021891a07c",
|
|
76
77
|
"devDependencies": {
|
|
77
78
|
"typescript": "^5.9.3"
|
|
78
79
|
}
|
package/plugins/cipher.ts
CHANGED
package/plugins/config.ts
CHANGED
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
* 配置插件
|
|
3
3
|
* 提供访问项目配置的能力
|
|
4
4
|
*/
|
|
5
|
+
import { beflyConfig } from '../befly.config.js';
|
|
5
6
|
|
|
6
|
-
// 类型导入
|
|
7
7
|
import type { Plugin } from '../types/plugin.js';
|
|
8
8
|
|
|
9
9
|
const plugin: Plugin = {
|
|
10
|
-
handler: (
|
|
11
|
-
|
|
12
|
-
return config || {};
|
|
10
|
+
handler: () => {
|
|
11
|
+
return beflyConfig;
|
|
13
12
|
}
|
|
14
13
|
};
|
|
15
14
|
|
package/plugins/db.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 数据库插件
|
|
2
|
+
* 数据库插件
|
|
3
3
|
* 初始化数据库连接和 SQL 管理器
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Logger } from '../lib/logger.js';
|
|
7
7
|
import { Connect } from '../lib/connect.js';
|
|
8
8
|
import { DbHelper } from '../lib/dbHelper.js';
|
|
9
|
+
|
|
9
10
|
import type { Plugin } from '../types/plugin.js';
|
|
10
11
|
import type { BeflyContext } from '../types/befly.js';
|
|
11
12
|
|
|
@@ -14,12 +15,11 @@ import type { BeflyContext } from '../types/befly.js';
|
|
|
14
15
|
*/
|
|
15
16
|
const dbPlugin: Plugin = {
|
|
16
17
|
after: ['logger'],
|
|
17
|
-
async handler(
|
|
18
|
+
async handler(befly: BeflyContext): Promise<DbHelper> {
|
|
18
19
|
let sql: any = null;
|
|
19
|
-
const config = this.config || {};
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
|
-
sql = await Connect.connectSql(
|
|
22
|
+
sql = await Connect.connectSql();
|
|
23
23
|
|
|
24
24
|
// 创建数据库管理器实例,直接传入 sql 对象
|
|
25
25
|
const dbManager = new DbHelper(befly, sql);
|
|
@@ -37,7 +37,6 @@ const dbPlugin: Plugin = {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// 插件内禁止直接退出进程,抛出异常交由主流程统一处理
|
|
41
40
|
throw error;
|
|
42
41
|
}
|
|
43
42
|
}
|
package/plugins/jwt.ts
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { Jwt } from '../lib/jwt.js';
|
|
6
|
+
import { beflyConfig } from '../befly.config.js';
|
|
6
7
|
|
|
7
8
|
import type { Plugin } from '../types/plugin.js';
|
|
8
9
|
|
|
9
10
|
const jwtPlugin: Plugin = {
|
|
10
|
-
handler: (
|
|
11
|
-
return new Jwt(
|
|
11
|
+
handler: () => {
|
|
12
|
+
return new Jwt(beflyConfig.auth);
|
|
12
13
|
}
|
|
13
14
|
};
|
|
14
15
|
|
package/plugins/logger.ts
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 日志插件
|
|
2
|
+
* 日志插件
|
|
3
3
|
* 提供全局日志功能
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Logger } from '../lib/logger.js';
|
|
7
|
+
import { beflyConfig } from '../befly.config.js';
|
|
8
|
+
|
|
7
9
|
import type { Plugin } from '../types/plugin.js';
|
|
8
|
-
import type { BeflyContext } from '../types/befly.js';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* 日志插件
|
|
12
13
|
*/
|
|
13
14
|
const loggerPlugin: Plugin = {
|
|
14
15
|
after: [],
|
|
15
|
-
async handler(
|
|
16
|
+
async handler(): Promise<typeof Logger> {
|
|
16
17
|
try {
|
|
17
18
|
// 配置 Logger
|
|
18
|
-
if (
|
|
19
|
-
Logger.configure(
|
|
19
|
+
if (beflyConfig.logger) {
|
|
20
|
+
Logger.configure(beflyConfig.logger);
|
|
20
21
|
}
|
|
21
22
|
return Logger;
|
|
22
23
|
} catch (error: any) {
|
|
23
|
-
// 插件内禁止直接退出进程,抛出异常交由主流程统一处理
|
|
24
24
|
throw error;
|
|
25
25
|
}
|
|
26
26
|
}
|
package/plugins/redis.ts
CHANGED
|
@@ -1,34 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Redis 插件
|
|
2
|
+
* Redis 插件
|
|
3
3
|
* 初始化 Redis 连接和助手工具
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Logger } from '../lib/logger.js';
|
|
7
7
|
import { Connect } from '../lib/connect.js';
|
|
8
8
|
import { RedisHelper } from '../lib/redisHelper.js';
|
|
9
|
+
import { beflyConfig } from '../befly.config.js';
|
|
10
|
+
|
|
9
11
|
import type { Plugin } from '../types/plugin.js';
|
|
10
|
-
import type { BeflyContext } from '../types/befly.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Redis 插件
|
|
14
15
|
*/
|
|
15
16
|
const redisPlugin: Plugin = {
|
|
16
17
|
after: ['logger'],
|
|
17
|
-
async handler(
|
|
18
|
-
const
|
|
18
|
+
async handler(): Promise<RedisHelper | Record<string, never>> {
|
|
19
|
+
const redisConfig = beflyConfig.redis || {};
|
|
19
20
|
try {
|
|
20
|
-
//
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
// 初始化 Redis 客户端(统一使用 connect.ts 的连接管理)
|
|
24
|
-
await Connect.connectRedis(config);
|
|
21
|
+
// 初始化 Redis 客户端
|
|
22
|
+
await Connect.connectRedis();
|
|
25
23
|
|
|
26
24
|
// 返回 RedisHelper 实例
|
|
27
|
-
return new RedisHelper(
|
|
25
|
+
return new RedisHelper(redisConfig.prefix);
|
|
28
26
|
} catch (error: any) {
|
|
29
27
|
Logger.error({ err: error }, 'Redis 初始化失败');
|
|
30
|
-
|
|
31
|
-
// 插件内禁止直接退出进程,抛出异常交由主流程统一处理
|
|
32
28
|
throw error;
|
|
33
29
|
}
|
|
34
30
|
}
|
package/router/static.ts
CHANGED
|
@@ -10,18 +10,15 @@ import { join } from 'pathe';
|
|
|
10
10
|
import { projectDir } from '../paths.js';
|
|
11
11
|
import { Logger } from '../lib/logger.js';
|
|
12
12
|
import { setCorsOptions } from '../util.js';
|
|
13
|
-
|
|
14
|
-
// 类型导入
|
|
15
|
-
import type { BeflyOptions } from '../types/befly.js';
|
|
13
|
+
import { beflyConfig } from '../befly.config.js';
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* 静态文件处理器工厂
|
|
19
|
-
* @param config - Befly 配置
|
|
20
17
|
*/
|
|
21
|
-
export function staticHandler(
|
|
18
|
+
export function staticHandler() {
|
|
22
19
|
return async (req: Request): Promise<Response> => {
|
|
23
20
|
// 设置 CORS 响应头
|
|
24
|
-
const corsHeaders = setCorsOptions(req,
|
|
21
|
+
const corsHeaders = setCorsOptions(req, beflyConfig.cors);
|
|
25
22
|
|
|
26
23
|
const url = new URL(req.url);
|
|
27
24
|
const filePath = join(projectDir, 'public', url.pathname);
|
package/sync/syncAll.ts
CHANGED
|
@@ -9,30 +9,25 @@ import { syncDbCommand } from './syncDb.js';
|
|
|
9
9
|
import { syncApiCommand } from './syncApi.js';
|
|
10
10
|
import { syncMenuCommand } from './syncMenu.js';
|
|
11
11
|
import { syncDevCommand } from './syncDev.js';
|
|
12
|
-
import
|
|
12
|
+
import { beflyConfig } from '../befly.config.js';
|
|
13
|
+
import type { SyncOptions } from '../types/index.js';
|
|
13
14
|
|
|
14
|
-
export async function syncAllCommand(
|
|
15
|
+
export async function syncAllCommand(options: SyncOptions = {}) {
|
|
15
16
|
try {
|
|
16
|
-
const startTime = Date.now();
|
|
17
|
-
|
|
18
17
|
// 0. 检查项目结构
|
|
19
18
|
await checkApp();
|
|
20
19
|
|
|
21
20
|
// 1. 同步数据库表结构
|
|
22
|
-
await syncDbCommand(
|
|
21
|
+
await syncDbCommand({ dryRun: false, force: options.force || false });
|
|
23
22
|
|
|
24
23
|
// 2. 同步接口(并缓存)
|
|
25
|
-
await syncApiCommand(
|
|
24
|
+
await syncApiCommand();
|
|
26
25
|
|
|
27
26
|
// 3. 同步菜单(并缓存)
|
|
28
|
-
await syncMenuCommand(
|
|
27
|
+
await syncMenuCommand();
|
|
29
28
|
|
|
30
29
|
// 4. 同步开发管理员(并缓存角色权限)
|
|
31
|
-
await syncDevCommand(
|
|
32
|
-
|
|
33
|
-
// 输出总结
|
|
34
|
-
const totalTimeSeconds = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
35
|
-
Logger.info({ duration: totalTimeSeconds }, '同步完成');
|
|
30
|
+
await syncDevCommand();
|
|
36
31
|
} catch (error: any) {
|
|
37
32
|
Logger.error({ err: error }, '同步过程中发生错误');
|
|
38
33
|
throw error;
|
package/sync/syncApi.ts
CHANGED
|
@@ -21,8 +21,9 @@ import { scanAddons, addonDirExists, getAddonDir } from 'befly-shared/addonHelpe
|
|
|
21
21
|
|
|
22
22
|
import { Logger } from '../lib/logger.js';
|
|
23
23
|
import { projectDir } from '../paths.js';
|
|
24
|
+
import { beflyConfig } from '../befly.config.js';
|
|
24
25
|
|
|
25
|
-
import type { SyncApiOptions, ApiInfo
|
|
26
|
+
import type { SyncApiOptions, ApiInfo } from '../types/index.js';
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* 从 API 文件中提取接口信息
|
|
@@ -215,7 +216,7 @@ async function deleteObsoleteRecords(helper: any, apiPaths: Set<string>): Promis
|
|
|
215
216
|
/**
|
|
216
217
|
* SyncApi 命令主函数
|
|
217
218
|
*/
|
|
218
|
-
export async function syncApiCommand(
|
|
219
|
+
export async function syncApiCommand(options: SyncApiOptions = {}): Promise<void> {
|
|
219
220
|
try {
|
|
220
221
|
if (options.plan) {
|
|
221
222
|
Logger.debug('[计划] 同步 API 接口到数据库(plan 模式不执行)');
|
|
@@ -223,7 +224,7 @@ export async function syncApiCommand(config: BeflyOptions, options: SyncApiOptio
|
|
|
223
224
|
}
|
|
224
225
|
|
|
225
226
|
// 连接数据库(SQL + Redis)
|
|
226
|
-
await Connect.connect(
|
|
227
|
+
await Connect.connect();
|
|
227
228
|
|
|
228
229
|
const helper = new DbHelper({ redis: new RedisHelper() } as any, Connect.getSql());
|
|
229
230
|
|
package/sync/syncDb.ts
CHANGED
|
@@ -26,8 +26,9 @@ import { modifyTable } from './syncDb/table.js';
|
|
|
26
26
|
import { createTable } from './syncDb/tableCreate.js';
|
|
27
27
|
import { applyFieldDefaults } from './syncDb/helpers.js';
|
|
28
28
|
import { setDbType } from './syncDb/constants.js';
|
|
29
|
+
import { beflyConfig } from '../befly.config.js';
|
|
29
30
|
import type { SQL } from 'bun';
|
|
30
|
-
import type {
|
|
31
|
+
import type { SyncDbOptions } from '../types/index.js';
|
|
31
32
|
|
|
32
33
|
// 全局 SQL 客户端实例
|
|
33
34
|
let sql: SQL | null = null;
|
|
@@ -44,20 +45,20 @@ const processedTables: string[] = [];
|
|
|
44
45
|
* 3. 扫描表定义文件(核心表、项目表、addon表)
|
|
45
46
|
* 4. 对比并应用表结构变更
|
|
46
47
|
*/
|
|
47
|
-
export async function syncDbCommand(
|
|
48
|
+
export async function syncDbCommand(options: SyncDbOptions = {}): Promise<void> {
|
|
48
49
|
try {
|
|
49
50
|
// 清空处理记录
|
|
50
51
|
processedTables.length = 0;
|
|
51
52
|
|
|
52
53
|
// 设置数据库类型(从配置获取)
|
|
53
|
-
const dbType =
|
|
54
|
+
const dbType = beflyConfig.db?.type || 'mysql';
|
|
54
55
|
setDbType(dbType);
|
|
55
56
|
|
|
56
57
|
// 验证表定义文件
|
|
57
58
|
await checkTable();
|
|
58
59
|
|
|
59
60
|
// 建立数据库连接并检查版本
|
|
60
|
-
sql = await Connect.connectSql(
|
|
61
|
+
sql = await Connect.connectSql();
|
|
61
62
|
await ensureDbVersion(sql);
|
|
62
63
|
|
|
63
64
|
// 初始化 Redis 连接(用于清理缓存)
|
|
@@ -116,7 +117,7 @@ export async function syncDbCommand(config: BeflyOptions, options: SyncDbOptions
|
|
|
116
117
|
applyFieldDefaults(fieldDef);
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
const dbName =
|
|
120
|
+
const dbName = beflyConfig.db?.database;
|
|
120
121
|
const existsTable = await tableExists(sql!, tableName, dbName);
|
|
121
122
|
|
|
122
123
|
// 读取 force 参数
|
package/sync/syncDev.ts
CHANGED
|
@@ -15,26 +15,27 @@ import { Connect } from '../lib/connect.js';
|
|
|
15
15
|
import { DbHelper } from '../lib/dbHelper.js';
|
|
16
16
|
import { RedisHelper } from '../lib/redisHelper.js';
|
|
17
17
|
import { CacheHelper } from '../lib/cacheHelper.js';
|
|
18
|
+
import { beflyConfig } from '../befly.config.js';
|
|
18
19
|
|
|
19
|
-
import type { SyncDevOptions, SyncDevStats
|
|
20
|
+
import type { SyncDevOptions, SyncDevStats } from '../types/index.js';
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* SyncDev 命令主函数
|
|
23
24
|
*/
|
|
24
|
-
export async function syncDevCommand(
|
|
25
|
+
export async function syncDevCommand(options: SyncDevOptions = {}): Promise<void> {
|
|
25
26
|
try {
|
|
26
27
|
if (options.plan) {
|
|
27
28
|
Logger.debug('[计划] 同步完成后将初始化/更新开发管理员账号(plan 模式不执行)');
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
if (!
|
|
32
|
+
if (!beflyConfig.devPassword) {
|
|
32
33
|
// 未配置开发者密码,跳过同步
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
// 连接数据库(SQL + Redis)
|
|
37
|
-
await Connect.connect(
|
|
38
|
+
await Connect.connect();
|
|
38
39
|
|
|
39
40
|
const helper = new DbHelper({ redis: new RedisHelper() } as any, Connect.getSql());
|
|
40
41
|
|
|
@@ -121,12 +122,12 @@ export async function syncDevCommand(config: BeflyOptions, options: SyncDevOptio
|
|
|
121
122
|
}
|
|
122
123
|
|
|
123
124
|
// 使用 bcrypt 加密密码
|
|
124
|
-
const hashed = await Cipher.hashPassword(
|
|
125
|
+
const hashed = await Cipher.hashPassword(beflyConfig.devPassword);
|
|
125
126
|
|
|
126
127
|
// 准备开发管理员数据
|
|
127
128
|
const devData = {
|
|
128
129
|
nickname: '开发者',
|
|
129
|
-
email:
|
|
130
|
+
email: beflyConfig.devEmail,
|
|
130
131
|
username: 'dev',
|
|
131
132
|
password: hashed,
|
|
132
133
|
roleId: devRole.id,
|
|
@@ -137,14 +138,14 @@ export async function syncDevCommand(config: BeflyOptions, options: SyncDevOptio
|
|
|
137
138
|
// 查询现有账号
|
|
138
139
|
const existing = await helper.getOne({
|
|
139
140
|
table: 'addon_admin_admin',
|
|
140
|
-
where: { email:
|
|
141
|
+
where: { email: beflyConfig.devEmail }
|
|
141
142
|
});
|
|
142
143
|
|
|
143
144
|
if (existing) {
|
|
144
145
|
// 更新现有账号
|
|
145
146
|
await helper.updData({
|
|
146
147
|
table: 'addon_admin_admin',
|
|
147
|
-
where: { email:
|
|
148
|
+
where: { email: beflyConfig.devEmail },
|
|
148
149
|
data: devData
|
|
149
150
|
});
|
|
150
151
|
} else {
|