befly 1.1.0 → 1.1.2
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/main.js +0 -12
- package/package.json +2 -2
- package/plugins/db.js +1 -2
- package/plugins/tool.js +45 -0
- package/utils/curd.js +0 -186
package/main.js
CHANGED
|
@@ -100,7 +100,6 @@ class Befly {
|
|
|
100
100
|
async loadPlugins() {
|
|
101
101
|
try {
|
|
102
102
|
const loadStartTime = Bun.nanoseconds();
|
|
103
|
-
Logger.info('开始加载插件...');
|
|
104
103
|
|
|
105
104
|
const glob = new Bun.Glob('*.js');
|
|
106
105
|
const corePlugins = [];
|
|
@@ -108,7 +107,6 @@ class Befly {
|
|
|
108
107
|
const loadedPluginNames = new Set(); // 用于跟踪已加载的插件名称
|
|
109
108
|
|
|
110
109
|
// 扫描核心插件目录
|
|
111
|
-
Logger.info('正在扫描核心插件...');
|
|
112
110
|
const corePluginsScanStart = Bun.nanoseconds();
|
|
113
111
|
for await (const file of glob.scan({
|
|
114
112
|
cwd: path.join(dirname2(import.meta.url), 'plugins'),
|
|
@@ -139,15 +137,11 @@ class Befly {
|
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
// 初始化核心插件
|
|
142
|
-
Logger.info('正在初始化核心插件...');
|
|
143
140
|
const corePluginsInitStart = Bun.nanoseconds();
|
|
144
141
|
for (const plugin of sortedCorePlugins) {
|
|
145
142
|
try {
|
|
146
|
-
const initStart = Bun.nanoseconds();
|
|
147
143
|
this.pluginLists.push(plugin);
|
|
148
144
|
this.appContext[plugin.pluginName] = typeof plugin?.onInit === 'function' ? await plugin?.onInit(this.appContext) : {};
|
|
149
|
-
const initTime = (Bun.nanoseconds() - initStart) / 1_000_000;
|
|
150
|
-
Logger.info(`核心插件 ${plugin.pluginName} 初始化耗时: ${initTime.toFixed(2)}ms`);
|
|
151
145
|
} catch (error) {
|
|
152
146
|
Logger.warn(`插件 ${plugin.pluginName} 初始化失败:`, error.message);
|
|
153
147
|
}
|
|
@@ -156,7 +150,6 @@ class Befly {
|
|
|
156
150
|
Logger.info(`核心插件初始化完成,耗时: ${corePluginsInitTime.toFixed(2)}ms`);
|
|
157
151
|
|
|
158
152
|
// 扫描用户插件目录
|
|
159
|
-
Logger.info('正在扫描用户插件...');
|
|
160
153
|
const userPluginsScanStart = Bun.nanoseconds();
|
|
161
154
|
for await (const file of glob.scan({
|
|
162
155
|
cwd: path.join(process.cwd(), 'plugins'),
|
|
@@ -193,15 +186,11 @@ class Befly {
|
|
|
193
186
|
|
|
194
187
|
// 初始化用户插件
|
|
195
188
|
if (userPlugins.length > 0) {
|
|
196
|
-
Logger.info('正在初始化用户插件...');
|
|
197
189
|
const userPluginsInitStart = Bun.nanoseconds();
|
|
198
190
|
for (const plugin of sortedUserPlugins) {
|
|
199
191
|
try {
|
|
200
|
-
const initStart = Bun.nanoseconds();
|
|
201
192
|
this.pluginLists.push(plugin);
|
|
202
193
|
this.appContext[plugin.pluginName] = typeof plugin?.onInit === 'function' ? await plugin?.onInit(this.appContext) : {};
|
|
203
|
-
const initTime = (Bun.nanoseconds() - initStart) / 1_000_000;
|
|
204
|
-
Logger.info(`用户插件 ${plugin.pluginName} 初始化耗时: ${initTime.toFixed(2)}ms`);
|
|
205
194
|
} catch (error) {
|
|
206
195
|
Logger.warn(`插件 ${plugin.pluginName} 初始化失败:`, error.message);
|
|
207
196
|
}
|
|
@@ -225,7 +214,6 @@ class Befly {
|
|
|
225
214
|
try {
|
|
226
215
|
const loadStartTime = Bun.nanoseconds();
|
|
227
216
|
const dirDisplayName = dirName === 'core' ? '核心' : '用户';
|
|
228
|
-
Logger.info(`开始加载${dirDisplayName}接口...`);
|
|
229
217
|
|
|
230
218
|
const coreApisDir = path.join(dirname2(import.meta.url), 'apis');
|
|
231
219
|
const userApisDir = path.join(process.cwd(), 'apis');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "befly",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Buma - 为 Bun 专属打造的 API 接口框架核心引擎",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"README.md",
|
|
50
50
|
"vitest.config.js"
|
|
51
51
|
],
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "d1a26096e103683507f21e2932cb0305e034c2d0"
|
|
53
53
|
}
|
package/plugins/db.js
CHANGED
package/plugins/tool.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
after: ['_redis', '_db'],
|
|
3
|
+
async onInit(befly) {
|
|
4
|
+
// 增强的更新方法 - 自动添加 updated_at
|
|
5
|
+
|
|
6
|
+
// 辅助函数:过滤掉 undefined 值和指定字段
|
|
7
|
+
const filterData = (obj, excludeFields = []) => {
|
|
8
|
+
return Object.fromEntries(Object.entries(obj).filter(([key, value]) => value !== undefined && !excludeFields.includes(key)));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
async updData(data) {
|
|
13
|
+
const updateData = {
|
|
14
|
+
...filterData(data, ['id', 'created_at', 'deleted_at']),
|
|
15
|
+
updated_at: Date.now()
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return updateData;
|
|
19
|
+
},
|
|
20
|
+
async insData(data) {
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
|
|
23
|
+
if (Array.isArray(data)) {
|
|
24
|
+
const data2 = await Promise.all(
|
|
25
|
+
data.map(async (item) => ({
|
|
26
|
+
...filterData(item),
|
|
27
|
+
id: await redis.genTimeID(),
|
|
28
|
+
created_at: now,
|
|
29
|
+
updated_at: now
|
|
30
|
+
}))
|
|
31
|
+
);
|
|
32
|
+
return data2;
|
|
33
|
+
} else {
|
|
34
|
+
const data2 = {
|
|
35
|
+
...filterData(data),
|
|
36
|
+
id: await redis.genTimeID(),
|
|
37
|
+
created_at: now,
|
|
38
|
+
updated_at: now
|
|
39
|
+
};
|
|
40
|
+
return data2;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
package/utils/curd.js
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { omitFields } from './util.js';
|
|
2
|
-
|
|
3
|
-
export class Crud {
|
|
4
|
-
constructor(db, redis, sql) {
|
|
5
|
-
this.db = db;
|
|
6
|
-
this.redis = redis;
|
|
7
|
-
this.sql = sql;
|
|
8
|
-
this.initMethods();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
initMethods() {
|
|
12
|
-
// 将所有 CRUD 方法直接挂载到 db 实例上
|
|
13
|
-
this.db.insData = this.insData.bind(this);
|
|
14
|
-
this.db.updData = this.updData.bind(this);
|
|
15
|
-
this.db.delData = this.delData.bind(this);
|
|
16
|
-
this.db.getOne = this.getOne.bind(this);
|
|
17
|
-
this.db.getList = this.getList.bind(this);
|
|
18
|
-
this.db.getAll = this.getAll.bind(this);
|
|
19
|
-
this.db.getCount = this.getCount.bind(this);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// 事务方法
|
|
23
|
-
async trans(callback) {
|
|
24
|
-
return await this.db.transaction().execute(async (trx) => {
|
|
25
|
-
// 创建一个临时的 Crud 实例,使用事务连接
|
|
26
|
-
const transactionCrud = new Crud(trx, this.redis, this.sql);
|
|
27
|
-
return await callback(transactionCrud);
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// 增强的插入方法 - 自动添加 ID 和时间戳,支持链式调用
|
|
32
|
-
insData(tableName, data) {
|
|
33
|
-
const insertQuery = this.db.insertInto(tableName);
|
|
34
|
-
const redis = this.redis;
|
|
35
|
-
|
|
36
|
-
insertQuery.exec = async function () {
|
|
37
|
-
const now = Date.now();
|
|
38
|
-
let processedData = data;
|
|
39
|
-
|
|
40
|
-
if (Array.isArray(data)) {
|
|
41
|
-
processedData = await Promise.all(
|
|
42
|
-
data.map(async (item) => ({
|
|
43
|
-
...item,
|
|
44
|
-
id: await redis.genTimeID(),
|
|
45
|
-
created_at: now,
|
|
46
|
-
updated_at: now
|
|
47
|
-
}))
|
|
48
|
-
);
|
|
49
|
-
} else {
|
|
50
|
-
processedData = {
|
|
51
|
-
...data,
|
|
52
|
-
id: await redis.genTimeID(),
|
|
53
|
-
created_at: now,
|
|
54
|
-
updated_at: now
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const result = await this.values(processedData).execute();
|
|
59
|
-
return { data: result }; // 返回统一格式
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
return insertQuery;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 增强的更新方法 - 自动添加 updated_at,支持链式调用
|
|
66
|
-
updData(tableName, data) {
|
|
67
|
-
// 剔除 undefined 值
|
|
68
|
-
const filteredData = Object.fromEntries(Object.entries(data).filter(([key, value]) => value !== undefined));
|
|
69
|
-
|
|
70
|
-
const updateData = {
|
|
71
|
-
...omitFields(filteredData, ['id', 'created_at', 'deleted_at']),
|
|
72
|
-
updated_at: Date.now()
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const updateQuery = this.db.updateTable(tableName).set(updateData);
|
|
76
|
-
|
|
77
|
-
updateQuery.exec = async function () {
|
|
78
|
-
const result = await this.execute();
|
|
79
|
-
return { data: result }; // 返回统一格式
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
return updateQuery;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// 增强的删除方法 - 支持链式调用
|
|
86
|
-
delData(tableName) {
|
|
87
|
-
const deleteQuery = this.db.deleteFrom(tableName);
|
|
88
|
-
|
|
89
|
-
deleteQuery.exec = async function () {
|
|
90
|
-
const result = await this.execute();
|
|
91
|
-
return { data: result }; // 返回统一格式
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
return deleteQuery;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// 查询单条记录 - 支持链式调用
|
|
98
|
-
getOne(tableName, fields) {
|
|
99
|
-
let selectQuery;
|
|
100
|
-
|
|
101
|
-
if (fields) {
|
|
102
|
-
selectQuery = Array.isArray(fields) ? this.db.selectFrom(tableName).select(fields) : this.db.selectFrom(tableName).select([fields]);
|
|
103
|
-
} else {
|
|
104
|
-
selectQuery = this.db.selectFrom(tableName).selectAll();
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// 默认过滤软删除的数据
|
|
108
|
-
selectQuery = selectQuery.where('state', '<>', 2);
|
|
109
|
-
|
|
110
|
-
// 添加 exec 方法,自动返回单条记录
|
|
111
|
-
selectQuery.exec = async function () {
|
|
112
|
-
const result = await this.executeTakeFirst();
|
|
113
|
-
return { data: result }; // 返回统一格式
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
return selectQuery;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// 查询列表 - 支持链式调用和分页
|
|
120
|
-
getList(tableName, fields, page = 1, pageSize = 20) {
|
|
121
|
-
let selectQuery;
|
|
122
|
-
|
|
123
|
-
if (fields) {
|
|
124
|
-
selectQuery = Array.isArray(fields) ? this.db.selectFrom(tableName).select(fields) : this.db.selectFrom(tableName).select([fields]);
|
|
125
|
-
} else {
|
|
126
|
-
selectQuery = this.db.selectFrom(tableName).selectAll();
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// 默认过滤软删除的数据
|
|
130
|
-
selectQuery = selectQuery.where('state', '<>', 2);
|
|
131
|
-
|
|
132
|
-
// 添加 exec 方法 - 支持分页,只返回数据列表
|
|
133
|
-
selectQuery.exec = async function () {
|
|
134
|
-
const offset = (page - 1) * pageSize;
|
|
135
|
-
const result = await this.limit(pageSize).offset(offset).execute();
|
|
136
|
-
return { data: result };
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
return selectQuery;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// 查询所有记录 - 支持链式调用
|
|
143
|
-
getAll(tableName, fields) {
|
|
144
|
-
let selectQuery;
|
|
145
|
-
|
|
146
|
-
if (fields) {
|
|
147
|
-
selectQuery = Array.isArray(fields) ? this.db.selectFrom(tableName).select(fields) : this.db.selectFrom(tableName).select([fields]);
|
|
148
|
-
} else {
|
|
149
|
-
selectQuery = this.db.selectFrom(tableName).selectAll();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// 默认过滤软删除的数据
|
|
153
|
-
selectQuery = selectQuery.where('state', '<>', 2);
|
|
154
|
-
|
|
155
|
-
// 添加 exec 方法,执行查询所有记录
|
|
156
|
-
selectQuery.exec = async function () {
|
|
157
|
-
const result = await this.execute();
|
|
158
|
-
return { data: result }; // 返回统一格式
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
return selectQuery;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 便捷的计数方法 - 支持链式调用
|
|
165
|
-
getCount(tableName) {
|
|
166
|
-
const sql = this.sql;
|
|
167
|
-
const countQuery = this.db
|
|
168
|
-
.selectFrom(tableName)
|
|
169
|
-
.select(sql`count(*)`.as('total'))
|
|
170
|
-
.where('state', '<>', 2);
|
|
171
|
-
|
|
172
|
-
// 添加便捷的 exec 方法
|
|
173
|
-
countQuery.exec = async function () {
|
|
174
|
-
const result = await this.executeTakeFirst();
|
|
175
|
-
const count = Number(result?.total || 0);
|
|
176
|
-
return { data: count }; // 返回统一格式
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
return countQuery;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// 获取原始数据库实例
|
|
183
|
-
getDb() {
|
|
184
|
-
return this.db;
|
|
185
|
-
}
|
|
186
|
-
}
|