befly 3.8.29 → 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 +91 -6
- package/checks/checkApi.ts +2 -1
- package/checks/checkApp.ts +31 -1
- package/checks/checkTable.ts +3 -2
- package/hooks/cors.ts +3 -3
- package/hooks/parser.ts +8 -6
- package/hooks/permission.ts +12 -5
- package/hooks/validator.ts +1 -1
- package/lib/cacheHelper.ts +73 -65
- package/lib/cipher.ts +2 -1
- package/lib/connect.ts +23 -52
- package/lib/dbHelper.ts +14 -11
- package/lib/jwt.ts +58 -437
- package/lib/logger.ts +76 -197
- package/lib/redisHelper.ts +163 -1
- package/lib/sqlBuilder.ts +2 -1
- package/lib/validator.ts +150 -384
- package/loader/loadApis.ts +4 -7
- package/loader/loadHooks.ts +6 -5
- package/loader/loadPlugins.ts +11 -13
- package/main.ts +26 -53
- package/package.json +10 -8
- package/paths.ts +0 -6
- package/plugins/cipher.ts +1 -1
- package/plugins/config.ts +3 -4
- package/plugins/db.ts +6 -7
- package/plugins/jwt.ts +7 -6
- package/plugins/logger.ts +6 -6
- package/plugins/redis.ts +9 -13
- package/router/api.ts +2 -2
- package/router/static.ts +4 -8
- package/sync/syncAll.ts +8 -13
- package/sync/syncApi.ts +14 -10
- package/sync/syncDb/apply.ts +1 -2
- package/sync/syncDb.ts +12 -15
- package/sync/syncDev.ts +19 -56
- package/sync/syncMenu.ts +182 -137
- package/tests/cacheHelper.test.ts +327 -0
- package/tests/dbHelper-columns.test.ts +5 -20
- package/tests/dbHelper-execute.test.ts +14 -68
- package/tests/fields-redis-cache.test.ts +5 -3
- package/tests/integration.test.ts +17 -32
- package/tests/jwt.test.ts +36 -94
- package/tests/logger.test.ts +32 -34
- package/tests/redisHelper.test.ts +271 -2
- package/tests/redisKeys.test.ts +76 -0
- package/tests/sync-connection.test.ts +0 -6
- package/tests/syncDb-constants.test.ts +12 -12
- package/tests/util.test.ts +5 -1
- package/tests/validator.test.ts +611 -85
- package/types/befly.d.ts +9 -15
- package/types/cache.d.ts +73 -0
- package/types/common.d.ts +10 -128
- package/types/database.d.ts +221 -5
- package/types/index.ts +6 -5
- package/types/plugin.d.ts +1 -4
- package/types/redis.d.ts +37 -2
- package/types/table.d.ts +175 -0
- package/config.ts +0 -70
- package/hooks/_rateLimit.ts +0 -64
- package/lib/regexAliases.ts +0 -59
- package/lib/xml.ts +0 -383
- package/tests/validator-advanced.test.ts +0 -653
- package/tests/xml.test.ts +0 -101
- 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 -43
- package/types/tool.d.ts +0 -67
- package/types/validator.d.ts +0 -43
package/loader/loadHooks.ts
CHANGED
|
@@ -7,21 +7,22 @@
|
|
|
7
7
|
import { Logger } from '../lib/logger.js';
|
|
8
8
|
import { coreHookDir } from '../paths.js';
|
|
9
9
|
import { scanModules } from '../util.js';
|
|
10
|
+
import { beflyConfig } from '../befly.config.js';
|
|
10
11
|
|
|
11
12
|
// 类型导入
|
|
12
13
|
import type { Hook } from '../types/hook.js';
|
|
13
14
|
|
|
14
|
-
export async function loadHooks(
|
|
15
|
+
export async function loadHooks(hooks: Hook[]): Promise<void> {
|
|
15
16
|
try {
|
|
16
17
|
// 1. 扫描核心钩子
|
|
17
|
-
const coreHooks = await scanModules<Hook>(coreHookDir, 'core', '钩子'
|
|
18
|
+
const coreHooks = await scanModules<Hook>(coreHookDir, 'core', '钩子');
|
|
18
19
|
|
|
19
20
|
// 2. 过滤禁用的钩子
|
|
20
|
-
const disableHooks =
|
|
21
|
+
const disableHooks = beflyConfig.disableHooks || [];
|
|
21
22
|
const enabledHooks = coreHooks.filter((hook) => !disableHooks.includes(hook.name));
|
|
22
23
|
|
|
23
24
|
if (disableHooks.length > 0) {
|
|
24
|
-
Logger.info(
|
|
25
|
+
Logger.info({ hooks: disableHooks }, '禁用钩子');
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
// 3. 按 order 排序
|
|
@@ -33,7 +34,7 @@ export async function loadHooks(pluginsConfig: Record<string, any> | undefined,
|
|
|
33
34
|
|
|
34
35
|
hooks.push(...sortedHooks);
|
|
35
36
|
} catch (error: any) {
|
|
36
|
-
Logger.error('加载钩子时发生错误'
|
|
37
|
+
Logger.error({ err: error }, '加载钩子时发生错误');
|
|
37
38
|
process.exit(1);
|
|
38
39
|
}
|
|
39
40
|
}
|
package/loader/loadPlugins.ts
CHANGED
|
@@ -3,33 +3,34 @@
|
|
|
3
3
|
* 负责扫描和初始化所有插件(核心、组件、项目)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { scanAddons, getAddonDir } from 'befly-
|
|
6
|
+
import { scanAddons, getAddonDir } from 'befly-shared/addonHelper';
|
|
7
7
|
|
|
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,11 +38,11 @@ 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) {
|
|
44
|
-
Logger.info(
|
|
45
|
+
Logger.info({ plugins: disablePlugins }, '禁用插件');
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
// 6. 排序与初始化
|
|
@@ -55,20 +56,17 @@ 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;
|
|
62
63
|
} catch (error: any) {
|
|
63
|
-
Logger.error(
|
|
64
|
+
Logger.error({ err: error, plugin: plugin.name }, '插件初始化失败');
|
|
64
65
|
process.exit(1);
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
} catch (error: any) {
|
|
68
|
-
Logger.error('加载插件时发生错误'
|
|
69
|
+
Logger.error({ err: error }, '加载插件时发生错误');
|
|
69
70
|
process.exit(1);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
// ==================== 钩子加载逻辑 ====================
|
|
74
|
-
// 已移动到 loadHooks.ts
|
package/main.ts
CHANGED
|
@@ -4,15 +4,11 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// ========== 外部依赖 ==========
|
|
7
|
-
import { calcPerfTime } from 'befly-
|
|
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
|
-
import { Jwt } from './lib/jwt.js';
|
|
13
11
|
import { Connect } from './lib/connect.js';
|
|
14
|
-
import { DbHelper } from './lib/dbHelper.js';
|
|
15
|
-
import { RedisHelper } from './lib/redisHelper.js';
|
|
16
12
|
import { loadPlugins } from './loader/loadPlugins.js';
|
|
17
13
|
import { loadHooks } from './loader/loadHooks.js';
|
|
18
14
|
import { loadApis } from './loader/loadApis.js';
|
|
@@ -22,8 +18,6 @@ import { checkApp } from './checks/checkApp.js';
|
|
|
22
18
|
import { checkTable } from './checks/checkTable.js';
|
|
23
19
|
import { checkApi } from './checks/checkApi.js';
|
|
24
20
|
import { syncAllCommand } from './sync/syncAll.js';
|
|
25
|
-
import { coreDir } from './paths.js';
|
|
26
|
-
import { defaultOptions } from './config.js';
|
|
27
21
|
import { isPrimaryProcess, getProcessRole } from './util.js';
|
|
28
22
|
|
|
29
23
|
// ========== 类型导入 ==========
|
|
@@ -32,6 +26,7 @@ import type { BeflyContext, BeflyOptions } from './types/befly.js';
|
|
|
32
26
|
import type { Plugin } from './types/plugin.js';
|
|
33
27
|
import type { Hook } from './types/hook.js';
|
|
34
28
|
import type { ApiRoute } from './types/api.js';
|
|
29
|
+
|
|
35
30
|
/**
|
|
36
31
|
* Befly 框架核心类
|
|
37
32
|
* 职责:管理应用上下文和生命周期
|
|
@@ -49,22 +44,8 @@ export class Befly {
|
|
|
49
44
|
/** 应用上下文 */
|
|
50
45
|
public context: BeflyContext = {};
|
|
51
46
|
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
constructor(options: BeflyOptions = {}) {
|
|
56
|
-
// 合并用户配置:用户配置 > 默认配置(最多 2 级)
|
|
57
|
-
for (const key in options) {
|
|
58
|
-
const value = options[key as keyof BeflyOptions];
|
|
59
|
-
if (value !== undefined && value !== null) {
|
|
60
|
-
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
61
|
-
this.config[key as keyof BeflyOptions] = { ...defaultOptions[key as keyof typeof defaultOptions], ...value } as any;
|
|
62
|
-
} else {
|
|
63
|
-
this.config[key as keyof BeflyOptions] = value as any;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
47
|
+
/** 配置引用(延迟加载) */
|
|
48
|
+
private config: BeflyOptions | null = null;
|
|
68
49
|
|
|
69
50
|
/**
|
|
70
51
|
* 启动完整的生命周期流程
|
|
@@ -74,36 +55,40 @@ export class Befly {
|
|
|
74
55
|
try {
|
|
75
56
|
const serverStartTime = Bun.nanoseconds();
|
|
76
57
|
|
|
58
|
+
// 0. 延迟加载配置(避免循环依赖)
|
|
59
|
+
const { beflyConfig } = await import('./befly.config.js');
|
|
60
|
+
this.config = beflyConfig;
|
|
61
|
+
|
|
77
62
|
// 1. 执行启动检查
|
|
78
63
|
await checkApp();
|
|
79
64
|
await checkTable();
|
|
80
65
|
await checkApi();
|
|
81
66
|
|
|
82
|
-
//
|
|
83
|
-
await loadPlugins(this.
|
|
67
|
+
// 2. 加载插件
|
|
68
|
+
await loadPlugins(this.plugins, this.context);
|
|
84
69
|
|
|
85
|
-
//
|
|
86
|
-
await loadHooks(this.
|
|
70
|
+
// 3. 加载钩子
|
|
71
|
+
await loadHooks(this.hooks);
|
|
87
72
|
|
|
88
|
-
//
|
|
73
|
+
// 4. 加载所有 API
|
|
89
74
|
await loadApis(this.apis);
|
|
90
75
|
|
|
91
|
-
//
|
|
76
|
+
// 5. 自动同步 (仅主进程执行,避免集群模式下重复执行)
|
|
92
77
|
if (isPrimaryProcess()) {
|
|
93
|
-
await syncAllCommand(
|
|
78
|
+
await syncAllCommand();
|
|
94
79
|
}
|
|
95
80
|
|
|
96
|
-
//
|
|
81
|
+
// 6. 启动 HTTP 服务器
|
|
97
82
|
const server = Bun.serve({
|
|
98
|
-
port: this.config
|
|
99
|
-
hostname: this.config
|
|
83
|
+
port: this.config!.appPort,
|
|
84
|
+
hostname: this.config!.appHost,
|
|
100
85
|
routes: {
|
|
101
|
-
'/': () => Response.json({ code: 0, msg: `${this.config
|
|
86
|
+
'/': () => Response.json({ code: 0, msg: `${this.config!.appName} 接口服务已启动` }),
|
|
102
87
|
'/api/*': apiHandler(this.apis, this.hooks, this.context),
|
|
103
|
-
'/*': staticHandler(
|
|
88
|
+
'/*': staticHandler()
|
|
104
89
|
},
|
|
105
90
|
error: (error: Error) => {
|
|
106
|
-
Logger.error('服务启动时发生错误'
|
|
91
|
+
Logger.error({ err: error }, '服务启动时发生错误');
|
|
107
92
|
return Response.json({ code: 1, msg: '内部服务器错误' });
|
|
108
93
|
}
|
|
109
94
|
});
|
|
@@ -113,11 +98,11 @@ export class Befly {
|
|
|
113
98
|
const roleLabel = processRole.role === 'primary' ? '主进程' : `工作进程 #${processRole.instanceId}`;
|
|
114
99
|
const envLabel = processRole.env === 'standalone' ? '' : ` [${processRole.env}]`;
|
|
115
100
|
|
|
116
|
-
Logger.info(`${this.config
|
|
101
|
+
Logger.info(`${this.config!.appName} 启动成功! (${roleLabel}${envLabel})`);
|
|
117
102
|
Logger.info(`服务器启动耗时: ${finalStartupTime}`);
|
|
118
|
-
Logger.info(`服务器监听地址: http://${this.config
|
|
103
|
+
Logger.info(`服务器监听地址: http://${this.config!.appHost}:${this.config!.appPort}`);
|
|
119
104
|
|
|
120
|
-
//
|
|
105
|
+
// 7. 注册优雅关闭处理
|
|
121
106
|
const gracefulShutdown = async (signal: string) => {
|
|
122
107
|
// 停止接收新请求
|
|
123
108
|
server.stop(true);
|
|
@@ -128,7 +113,7 @@ export class Befly {
|
|
|
128
113
|
await Connect.disconnect();
|
|
129
114
|
Logger.info('数据库连接已关闭');
|
|
130
115
|
} catch (error: any) {
|
|
131
|
-
Logger.error('
|
|
116
|
+
Logger.error({ err: error }, '关闭数据库连接时出错');
|
|
132
117
|
}
|
|
133
118
|
|
|
134
119
|
Logger.info('服务器已优雅关闭');
|
|
@@ -140,20 +125,8 @@ export class Befly {
|
|
|
140
125
|
|
|
141
126
|
return server;
|
|
142
127
|
} catch (error: any) {
|
|
143
|
-
Logger.error('项目启动失败'
|
|
128
|
+
Logger.error({ err: error }, '项目启动失败');
|
|
144
129
|
process.exit(1);
|
|
145
130
|
}
|
|
146
131
|
}
|
|
147
132
|
}
|
|
148
|
-
|
|
149
|
-
// 核心类和工具导出
|
|
150
|
-
export {
|
|
151
|
-
// 配置
|
|
152
|
-
Logger,
|
|
153
|
-
Cipher,
|
|
154
|
-
Jwt,
|
|
155
|
-
Database,
|
|
156
|
-
DbHelper,
|
|
157
|
-
RedisHelper,
|
|
158
|
-
coreDir
|
|
159
|
-
};
|
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,
|
|
@@ -15,12 +15,10 @@
|
|
|
15
15
|
"types": "./main.ts",
|
|
16
16
|
"default": "./main.ts"
|
|
17
17
|
},
|
|
18
|
-
"
|
|
19
|
-
"types": "./types/index.ts",
|
|
20
|
-
"default": "./types/index.ts"
|
|
21
|
-
}
|
|
18
|
+
"./*": "./*"
|
|
22
19
|
},
|
|
23
20
|
"scripts": {
|
|
21
|
+
"test": "bun test",
|
|
24
22
|
"bundler": "bun build ./main.ts --outfile ./main.single.ts --minify --target bun"
|
|
25
23
|
},
|
|
26
24
|
"keywords": [
|
|
@@ -66,12 +64,16 @@
|
|
|
66
64
|
"bun": ">=1.3.0"
|
|
67
65
|
},
|
|
68
66
|
"dependencies": {
|
|
69
|
-
"befly-
|
|
67
|
+
"befly-shared": "^1.1.2",
|
|
70
68
|
"chalk": "^5.6.2",
|
|
71
69
|
"es-toolkit": "^1.42.0",
|
|
72
|
-
"
|
|
70
|
+
"fast-jwt": "^6.0.2",
|
|
71
|
+
"fast-xml-parser": "^5.3.2",
|
|
72
|
+
"pathe": "^2.0.3",
|
|
73
|
+
"pino": "^10.1.0",
|
|
74
|
+
"pino-roll": "^4.0.0"
|
|
73
75
|
},
|
|
74
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "d9a4c57539f6eb692d7db6c7fd800e021891a07c",
|
|
75
77
|
"devDependencies": {
|
|
76
78
|
"typescript": "^5.9.3"
|
|
77
79
|
}
|
package/paths.ts
CHANGED
|
@@ -46,9 +46,6 @@ export const corePluginDir = join(__dirname, 'plugins');
|
|
|
46
46
|
*/
|
|
47
47
|
export const coreHookDir = join(__dirname, 'hooks');
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
* Core 框架 API 目录
|
|
51
|
-
|
|
52
49
|
/**
|
|
53
50
|
* Core 框架 API 目录
|
|
54
51
|
* @description packages/core/apis/
|
|
@@ -93,9 +90,6 @@ export const projectPluginDir = join(projectDir, 'plugins');
|
|
|
93
90
|
*/
|
|
94
91
|
export const projectHookDir = join(projectDir, 'hooks');
|
|
95
92
|
|
|
96
|
-
/**
|
|
97
|
-
* 项目 API 目录
|
|
98
|
-
|
|
99
93
|
/**
|
|
100
94
|
* 项目 API 目录
|
|
101
95
|
* @description {projectDir}/apis/
|
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,30 +15,28 @@ 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);
|
|
26
26
|
|
|
27
27
|
return dbManager;
|
|
28
28
|
} catch (error: any) {
|
|
29
|
-
Logger.error('数据库初始化失败'
|
|
29
|
+
Logger.error({ err: error }, '数据库初始化失败');
|
|
30
30
|
|
|
31
31
|
// 清理资源
|
|
32
32
|
if (sql) {
|
|
33
33
|
try {
|
|
34
34
|
await sql.close();
|
|
35
35
|
} catch (cleanupError: any) {
|
|
36
|
-
Logger.error('
|
|
36
|
+
Logger.error({ err: cleanupError }, '清理连接池失败');
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// 插件内禁止直接退出进程,抛出异常交由主流程统一处理
|
|
41
40
|
throw error;
|
|
42
41
|
}
|
|
43
42
|
}
|
package/plugins/jwt.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* JWT 插件
|
|
3
|
-
* 提供 JSON Web Token 签名和验证功能
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
import { Jwt } from '../lib/jwt.js';
|
|
6
|
+
import { beflyConfig } from '../befly.config.js';
|
|
7
7
|
|
|
8
8
|
import type { Plugin } from '../types/plugin.js';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return Jwt;
|
|
10
|
+
const jwtPlugin: Plugin = {
|
|
11
|
+
handler: () => {
|
|
12
|
+
return new Jwt(beflyConfig.auth);
|
|
14
13
|
}
|
|
15
|
-
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export default jwtPlugin;
|
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
|
-
Logger.error('Redis 初始化失败'
|
|
30
|
-
|
|
31
|
-
// 插件内禁止直接退出进程,抛出异常交由主流程统一处理
|
|
27
|
+
Logger.error({ err: error }, 'Redis 初始化失败');
|
|
32
28
|
throw error;
|
|
33
29
|
}
|
|
34
30
|
}
|
package/router/api.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// 外部依赖
|
|
7
|
-
import { genShortId } from 'befly-
|
|
7
|
+
import { genShortId } from 'befly-shared/genShortId';
|
|
8
8
|
|
|
9
9
|
// 相对导入
|
|
10
10
|
import { FinalResponse } from '../util.js';
|
|
@@ -88,7 +88,7 @@ export function apiHandler(apis: Map<string, ApiRoute>, hooks: Hook[], context:
|
|
|
88
88
|
} catch (err: any) {
|
|
89
89
|
// 全局错误处理
|
|
90
90
|
const errorPath = ctx.api ? apiPath : req.url;
|
|
91
|
-
Logger.error(
|
|
91
|
+
Logger.error({ err: err, path: errorPath }, '请求错误');
|
|
92
92
|
ctx.result = {
|
|
93
93
|
code: 1,
|
|
94
94
|
msg: '内部服务错误'
|
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);
|
|
@@ -55,8 +52,7 @@ export function staticHandler(config: BeflyOptions) {
|
|
|
55
52
|
);
|
|
56
53
|
}
|
|
57
54
|
} catch (error: any) {
|
|
58
|
-
|
|
59
|
-
Logger.error('静态文件处理失败', error);
|
|
55
|
+
Logger.error({ err: error }, '静态文件处理失败');
|
|
60
56
|
|
|
61
57
|
return Response.json(
|
|
62
58
|
{
|
package/sync/syncAll.ts
CHANGED
|
@@ -9,32 +9,27 @@ 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(`同步完成 (耗时 ${totalTimeSeconds}s)`);
|
|
30
|
+
await syncDevCommand();
|
|
36
31
|
} catch (error: any) {
|
|
37
|
-
Logger.error('同步过程中发生错误'
|
|
32
|
+
Logger.error({ err: error }, '同步过程中发生错误');
|
|
38
33
|
throw error;
|
|
39
34
|
}
|
|
40
35
|
}
|