befly 2.1.1 → 2.2.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 +1 -1
- package/apis/health/info.js +1 -1
- package/apis/tool/tokenCheck.js +1 -1
- package/bunfig.toml +3 -0
- package/checks/table.js +3 -3
- package/config/env.js +0 -2
- package/main.js +64 -35
- package/package.json +8 -22
- package/plugins/db.js +7 -587
- package/plugins/logger.js +2 -1
- package/plugins/redis.js +7 -64
- package/plugins/tool.js +3 -40
- package/scripts/syncDb.js +8 -16
- package/utils/api.js +1 -1
- package/utils/{util.js → index.js} +82 -24
- package/utils/jwt.js +63 -13
- package/utils/logger.js +1 -1
- package/utils/redisHelper.js +74 -0
- package/utils/sqlManager.js +471 -0
- package/utils/tool.js +31 -0
- package/utils/validate.js +2 -2
- package/.gitignore +0 -94
- package/libs/jwt.js +0 -97
- /package/utils/{curd.js → sqlBuilder.js} +0 -0
- /package/{libs → utils}/xml.js +0 -0
package/README.md
CHANGED
package/apis/health/info.js
CHANGED
package/apis/tool/tokenCheck.js
CHANGED
package/bunfig.toml
ADDED
package/checks/table.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { Logger } from '../utils/logger.js';
|
|
3
|
-
import { parseFieldRule, validateFieldName, validateFieldType, validateMinMax, validateDefaultValue, validateIndex, validateRegex } from '../utils/
|
|
3
|
+
import { parseFieldRule, validateFieldName, validateFieldType, validateMinMax, validateDefaultValue, validateIndex, validateRegex } from '../utils/index.js';
|
|
4
4
|
import { __dirtables, getProjectDir } from '../system.js';
|
|
5
5
|
|
|
6
|
-
// 所有校验函数均复用 utils/
|
|
6
|
+
// 所有校验函数均复用 utils/index.js 导出的实现
|
|
7
7
|
|
|
8
|
-
export
|
|
8
|
+
export const checkTable = async () => {
|
|
9
9
|
try {
|
|
10
10
|
const tablesGlob = new Bun.Glob('*.json');
|
|
11
11
|
|
package/config/env.js
CHANGED
|
@@ -25,14 +25,12 @@ export const Env = {
|
|
|
25
25
|
TZ: process.env.TZ,
|
|
26
26
|
// 数据库配置
|
|
27
27
|
MYSQL_ENABLE: Number(process.env.MYSQL_ENABLE),
|
|
28
|
-
MYSQL_URL: process.env.MYSQL_URL,
|
|
29
28
|
MYSQL_HOST: process.env.MYSQL_HOST,
|
|
30
29
|
MYSQL_PORT: Number(process.env.MYSQL_PORT),
|
|
31
30
|
MYSQL_DB: process.env.MYSQL_DB,
|
|
32
31
|
MYSQL_USER: process.env.MYSQL_USER,
|
|
33
32
|
MYSQL_PASSWORD: process.env.MYSQL_PASSWORD,
|
|
34
33
|
MYSQL_DEBUG: Number(process.env.MYSQL_DEBUG),
|
|
35
|
-
MYSQL_POOL_TIMEOUT: Number(process.env.MYSQL_POOL_TIMEOUT),
|
|
36
34
|
MYSQL_POOL_MAX: Number(process.env.MYSQL_POOL_MAX),
|
|
37
35
|
// Redis配置
|
|
38
36
|
REDIS_URL: process.env.REDIS_URL,
|
package/main.js
CHANGED
|
@@ -5,10 +5,10 @@ import { Logger } from './utils/logger.js';
|
|
|
5
5
|
import { Jwt } from './utils/jwt.js';
|
|
6
6
|
import { validator } from './utils/validate.js';
|
|
7
7
|
import { Crypto2 } from './utils/crypto.js';
|
|
8
|
-
import { Xml } from './
|
|
8
|
+
import { Xml } from './utils/xml.js';
|
|
9
9
|
import { SyncDb } from './scripts/syncDb.js';
|
|
10
10
|
import { __dirchecks, __dirplugins, __dirapis, getProjectDir } from './system.js';
|
|
11
|
-
import { isEmptyObject, isType, pickFields, sortPlugins, RYes, RNo, filterLogFields, setCorsOptions,
|
|
11
|
+
import { isEmptyObject, isType, pickFields, sortPlugins, RYes, RNo, filterLogFields, setCorsOptions, calcPerfTime } from './utils/index.js';
|
|
12
12
|
|
|
13
13
|
class Befly {
|
|
14
14
|
constructor(options = {}) {
|
|
@@ -48,7 +48,7 @@ class Befly {
|
|
|
48
48
|
// 执行默认导出的函数
|
|
49
49
|
if (typeof check.default === 'function') {
|
|
50
50
|
const checkResult = await check.default(this.appContext);
|
|
51
|
-
const singleCheckTime =
|
|
51
|
+
const singleCheckTime = calcPerfTime(singleCheckStart);
|
|
52
52
|
|
|
53
53
|
if (checkResult === true) {
|
|
54
54
|
passedChecks++;
|
|
@@ -58,12 +58,12 @@ class Befly {
|
|
|
58
58
|
failedChecks++;
|
|
59
59
|
}
|
|
60
60
|
} else {
|
|
61
|
-
const singleCheckTime =
|
|
61
|
+
const singleCheckTime = calcPerfTime(singleCheckStart);
|
|
62
62
|
Logger.warn(`文件 ${fileName} 未导出默认函数,耗时: ${singleCheckTime}`);
|
|
63
63
|
failedChecks++;
|
|
64
64
|
}
|
|
65
65
|
} catch (error) {
|
|
66
|
-
const singleCheckTime =
|
|
66
|
+
const singleCheckTime = calcPerfTime(singleCheckStart);
|
|
67
67
|
Logger.error({
|
|
68
68
|
msg: `检查失败 ${fileName},耗时: ${singleCheckTime}`,
|
|
69
69
|
error: error.message,
|
|
@@ -73,7 +73,7 @@ class Befly {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
const totalCheckTime =
|
|
76
|
+
const totalCheckTime = calcPerfTime(checkStartTime);
|
|
77
77
|
|
|
78
78
|
// 输出检查结果统计
|
|
79
79
|
Logger.info(`系统检查完成! 总耗时: ${totalCheckTime},总检查数: ${totalChecks}, 通过: ${passedChecks}, 失败: ${failedChecks}`);
|
|
@@ -103,6 +103,7 @@ class Befly {
|
|
|
103
103
|
const corePlugins = [];
|
|
104
104
|
const userPlugins = [];
|
|
105
105
|
const loadedPluginNames = new Set(); // 用于跟踪已加载的插件名称
|
|
106
|
+
let hadPluginError = false; // 统一记录插件阶段是否有错误
|
|
106
107
|
|
|
107
108
|
// 扫描核心插件目录
|
|
108
109
|
const corePluginsScanStart = Bun.nanoseconds();
|
|
@@ -114,18 +115,27 @@ class Befly {
|
|
|
114
115
|
const fileName = path.basename(file, '.js');
|
|
115
116
|
if (fileName.startsWith('_')) continue;
|
|
116
117
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
118
|
+
try {
|
|
119
|
+
const importStart = Bun.nanoseconds();
|
|
120
|
+
const plugin = await import(file);
|
|
121
|
+
const importTime = calcPerfTime(importStart);
|
|
122
|
+
|
|
123
|
+
const pluginInstance = plugin.default;
|
|
124
|
+
pluginInstance.pluginName = fileName;
|
|
125
|
+
corePlugins.push(pluginInstance);
|
|
126
|
+
loadedPluginNames.add(fileName); // 记录已加载的核心插件名称
|
|
127
|
+
|
|
128
|
+
Logger.info(`核心插件 ${fileName} 导入耗时: ${importTime}`);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
hadPluginError = true;
|
|
131
|
+
Logger.error({
|
|
132
|
+
msg: `核心插件 ${fileName} 导入失败`,
|
|
133
|
+
error: err.message,
|
|
134
|
+
stack: err.stack
|
|
135
|
+
});
|
|
136
|
+
}
|
|
127
137
|
}
|
|
128
|
-
const corePluginsScanTime =
|
|
138
|
+
const corePluginsScanTime = calcPerfTime(corePluginsScanStart);
|
|
129
139
|
Logger.info(`核心插件扫描完成,耗时: ${corePluginsScanTime},共找到 ${corePlugins.length} 个插件`);
|
|
130
140
|
|
|
131
141
|
const sortedCorePlugins = sortPlugins(corePlugins);
|
|
@@ -141,10 +151,11 @@ class Befly {
|
|
|
141
151
|
this.pluginLists.push(plugin);
|
|
142
152
|
this.appContext[plugin.pluginName] = typeof plugin?.onInit === 'function' ? await plugin?.onInit(this.appContext) : {};
|
|
143
153
|
} catch (error) {
|
|
144
|
-
|
|
154
|
+
hadPluginError = true;
|
|
155
|
+
Logger.warn(`插件 ${plugin.pluginName} 初始化失败: ${error.message}`);
|
|
145
156
|
}
|
|
146
157
|
}
|
|
147
|
-
const corePluginsInitTime =
|
|
158
|
+
const corePluginsInitTime = calcPerfTime(corePluginsInitStart);
|
|
148
159
|
Logger.info(`核心插件初始化完成,耗时: ${corePluginsInitTime}`);
|
|
149
160
|
|
|
150
161
|
// 扫描用户插件目录
|
|
@@ -163,17 +174,26 @@ class Befly {
|
|
|
163
174
|
continue;
|
|
164
175
|
}
|
|
165
176
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
177
|
+
try {
|
|
178
|
+
const importStart = Bun.nanoseconds();
|
|
179
|
+
const plugin = await import(file);
|
|
180
|
+
const importTime = calcPerfTime(importStart);
|
|
169
181
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
182
|
+
const pluginInstance = plugin.default;
|
|
183
|
+
pluginInstance.pluginName = fileName;
|
|
184
|
+
userPlugins.push(pluginInstance);
|
|
173
185
|
|
|
174
|
-
|
|
186
|
+
Logger.info(`用户插件 ${fileName} 导入耗时: ${importTime}`);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
hadPluginError = true;
|
|
189
|
+
Logger.error({
|
|
190
|
+
msg: `用户插件 ${fileName} 导入失败`,
|
|
191
|
+
error: err.message,
|
|
192
|
+
stack: err.stack
|
|
193
|
+
});
|
|
194
|
+
}
|
|
175
195
|
}
|
|
176
|
-
const userPluginsScanTime =
|
|
196
|
+
const userPluginsScanTime = calcPerfTime(userPluginsScanStart);
|
|
177
197
|
Logger.info(`用户插件扫描完成,耗时: ${userPluginsScanTime},共找到 ${userPlugins.length} 个插件`);
|
|
178
198
|
|
|
179
199
|
const sortedUserPlugins = sortPlugins(userPlugins);
|
|
@@ -190,22 +210,31 @@ class Befly {
|
|
|
190
210
|
this.pluginLists.push(plugin);
|
|
191
211
|
this.appContext[plugin.pluginName] = typeof plugin?.onInit === 'function' ? await plugin?.onInit(this.appContext) : {};
|
|
192
212
|
} catch (error) {
|
|
193
|
-
|
|
213
|
+
hadPluginError = true;
|
|
214
|
+
Logger.warn(`插件 ${plugin.pluginName} 初始化失败: ${error.message}`);
|
|
194
215
|
}
|
|
195
216
|
}
|
|
196
|
-
const userPluginsInitTime =
|
|
217
|
+
const userPluginsInitTime = calcPerfTime(userPluginsInitStart);
|
|
197
218
|
Logger.info(`用户插件初始化完成,耗时: ${userPluginsInitTime}`);
|
|
198
219
|
}
|
|
199
220
|
|
|
200
|
-
const totalLoadTime =
|
|
221
|
+
const totalLoadTime = calcPerfTime(loadStartTime);
|
|
201
222
|
const totalPluginCount = sortedCorePlugins.length + sortedUserPlugins.length;
|
|
202
223
|
Logger.info(`插件加载完成! 总耗时: ${totalLoadTime},共加载 ${totalPluginCount} 个插件`);
|
|
224
|
+
|
|
225
|
+
// 如果任意插件导入或初始化失败,统一退出进程
|
|
226
|
+
if (hadPluginError) {
|
|
227
|
+
Logger.error('检测到插件导入或初始化失败,进程即将退出');
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
203
230
|
} catch (error) {
|
|
204
231
|
Logger.error({
|
|
205
232
|
msg: '加载插件时发生错误',
|
|
206
233
|
error: error.message,
|
|
207
234
|
stack: error.stack
|
|
208
235
|
});
|
|
236
|
+
// 兜底退出,避免服务在插件阶段异常后继续运行
|
|
237
|
+
process.exit(1);
|
|
209
238
|
}
|
|
210
239
|
}
|
|
211
240
|
async loadApis(dirName) {
|
|
@@ -257,11 +286,11 @@ class Befly {
|
|
|
257
286
|
api.route = `${api.method.toUpperCase()}/api/${dirName}/${apiPath}`;
|
|
258
287
|
this.apiRoutes.set(api.route, api);
|
|
259
288
|
|
|
260
|
-
const singleApiTime =
|
|
289
|
+
const singleApiTime = calcPerfTime(singleApiStart);
|
|
261
290
|
loadedApis++;
|
|
262
291
|
// Logger.info(`${dirDisplayName}接口 ${apiPath} 加载成功,耗时: ${singleApiTime}`);
|
|
263
292
|
} catch (error) {
|
|
264
|
-
const singleApiTime =
|
|
293
|
+
const singleApiTime = calcPerfTime(singleApiStart);
|
|
265
294
|
failedApis++;
|
|
266
295
|
Logger.error({
|
|
267
296
|
msg: `${dirDisplayName}接口 ${apiPath} 加载失败,耗时: ${singleApiTime}`,
|
|
@@ -271,7 +300,7 @@ class Befly {
|
|
|
271
300
|
}
|
|
272
301
|
}
|
|
273
302
|
|
|
274
|
-
const totalLoadTime =
|
|
303
|
+
const totalLoadTime = calcPerfTime(loadStartTime);
|
|
275
304
|
Logger.info(`${dirDisplayName}接口加载完成! 总耗时: ${totalLoadTime},总数: ${totalApis}, 成功: ${loadedApis}, 失败: ${failedApis}`);
|
|
276
305
|
} catch (error) {
|
|
277
306
|
Logger.error({
|
|
@@ -294,7 +323,7 @@ class Befly {
|
|
|
294
323
|
await this.loadApis('core');
|
|
295
324
|
await this.loadApis('app');
|
|
296
325
|
|
|
297
|
-
const totalStartupTime =
|
|
326
|
+
const totalStartupTime = calcPerfTime(serverStartTime);
|
|
298
327
|
Logger.info(`服务器启动准备完成,总耗时: ${totalStartupTime}`);
|
|
299
328
|
|
|
300
329
|
const server = Bun.serve({
|
|
@@ -528,7 +557,7 @@ class Befly {
|
|
|
528
557
|
}
|
|
529
558
|
});
|
|
530
559
|
|
|
531
|
-
const finalStartupTime =
|
|
560
|
+
const finalStartupTime = calcPerfTime(serverStartTime);
|
|
532
561
|
Logger.info(`Befly 服务器启动成功! 完整启动耗时: ${finalStartupTime}`);
|
|
533
562
|
Logger.info(`服务器监听地址: http://${Env.APP_HOST}:${Env.APP_PORT}`);
|
|
534
563
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Buma - 为 Bun 专属打造的 API 接口框架核心引擎",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -13,15 +13,9 @@
|
|
|
13
13
|
".": "./main.js"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
|
16
|
-
"ra": "bun run release.js
|
|
17
|
-
"rb": "bun run release.js
|
|
18
|
-
"rc": "bun run release.js
|
|
19
|
-
"test": "bun test",
|
|
20
|
-
"test:unit": "bun test tests",
|
|
21
|
-
"test:jwt": "bun test tests/jwt.test.js",
|
|
22
|
-
"dev": "bun run project/main.js",
|
|
23
|
-
"server": "bunx --bun pm2 start pm2.config.cjs -a",
|
|
24
|
-
"syncDb": "bun run scripts/syncDb.js"
|
|
16
|
+
"ra": "bun run ../release.js --major",
|
|
17
|
+
"rb": "bun run ../release.js --minor",
|
|
18
|
+
"rc": "bun run ../release.js --patch"
|
|
25
19
|
},
|
|
26
20
|
"keywords": [
|
|
27
21
|
"bun",
|
|
@@ -40,7 +34,6 @@
|
|
|
40
34
|
"apis/",
|
|
41
35
|
"checks/",
|
|
42
36
|
"config/",
|
|
43
|
-
"libs/",
|
|
44
37
|
"plugins/",
|
|
45
38
|
"scripts/",
|
|
46
39
|
"tables/",
|
|
@@ -52,25 +45,18 @@
|
|
|
52
45
|
".npmrc",
|
|
53
46
|
".prettierignore",
|
|
54
47
|
".prettierrc",
|
|
48
|
+
"bunfig.toml",
|
|
55
49
|
"LICENSE",
|
|
56
50
|
"main.js",
|
|
57
51
|
"system.js",
|
|
58
52
|
"package.json",
|
|
59
|
-
"README.md"
|
|
60
|
-
"USEAGE.md",
|
|
61
|
-
"vitest.config.js"
|
|
53
|
+
"README.md"
|
|
62
54
|
],
|
|
63
|
-
"gitHead": "1dc5f118a723969456559e758e2ba889f4601224",
|
|
64
|
-
"dependencies": {},
|
|
65
55
|
"simple-git-hooks": {
|
|
66
56
|
"pre-commit": "bunx --bun lint-staged"
|
|
67
57
|
},
|
|
68
58
|
"lint-staged": {
|
|
69
59
|
"*.{js,css,scss,less,ts,jsx,vue,html,json,md,yaml}": "bunx --bun prettier --write --cache --ignore-unknown"
|
|
70
60
|
},
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
"prettier": "^3.6.2",
|
|
74
|
-
"simple-git-hooks": "^2.13.1"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
61
|
+
"gitHead": "1dc5f118a723969456559e758e2ba889f4601224"
|
|
62
|
+
}
|