befly 3.4.16 → 3.5.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/commands/build.ts CHANGED
@@ -4,7 +4,6 @@
4
4
 
5
5
  import { join } from 'pathe';
6
6
  import { existsSync } from 'node:fs';
7
- import ora from 'ora';
8
7
  import { Logger } from '../lib/logger.js';
9
8
  import { getProjectRoot } from './util.js';
10
9
 
@@ -28,11 +27,7 @@ export async function buildCommand(options: BuildOptions) {
28
27
  // 使用内置默认入口文件
29
28
  const entryFile = join(import.meta.dir, '..', 'entry.ts');
30
29
 
31
- const spinner = ora({
32
- text: '正在构建项目...',
33
- color: 'cyan',
34
- spinner: 'dots'
35
- }).start();
30
+ Logger.info('正在构建项目...');
36
31
 
37
32
  const args = ['build', entryFile, '--outdir', options.outdir, '--target', 'bun'];
38
33
 
@@ -53,10 +48,10 @@ export async function buildCommand(options: BuildOptions) {
53
48
  await proc.exited;
54
49
 
55
50
  if (proc.exitCode === 0) {
56
- spinner.succeed('项目构建完成');
51
+ Logger.success('项目构建完成');
57
52
  Logger.success(`输出目录: ${options.outdir}`);
58
53
  } else {
59
- spinner.fail('项目构建失败');
54
+ Logger.error('项目构建失败');
60
55
  process.exit(1);
61
56
  }
62
57
  } catch (error) {
package/commands/index.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
- * Build、Start、Sync、Addon、SyncApi、SyncMenu、SyncDev 命令实现
2
+ * Build、Start、Sync、SyncApi、SyncMenu、SyncDev 命令实现
3
3
  */
4
4
 
5
5
  import { join } from 'pathe';
6
6
  import { existsSync } from 'node:fs';
7
- import ora from 'ora';
8
7
  import { Logger } from '../lib/logger.js';
9
8
  import { getProjectRoot } from './util.js';
10
9
 
@@ -25,11 +24,7 @@ export async function buildCommand(options: BuildOptions) {
25
24
  process.exit(1);
26
25
  }
27
26
 
28
- const spinner = ora({
29
- text: '正在构建项目...',
30
- color: 'cyan',
31
- spinner: 'dots'
32
- }).start();
27
+ Logger.info('正在构建项目...');
33
28
 
34
29
  const args = ['build', mainFile, '--outdir', options.outdir, '--target', 'bun'];
35
30
 
@@ -50,10 +45,10 @@ export async function buildCommand(options: BuildOptions) {
50
45
  await proc.exited;
51
46
 
52
47
  if (proc.exitCode === 0) {
53
- spinner.succeed('项目构建完成');
48
+ Logger.success('项目构建完成');
54
49
  Logger.success(`输出目录: ${options.outdir}`);
55
50
  } else {
56
- spinner.fail('项目构建失败');
51
+ Logger.error('项目构建失败');
57
52
  process.exit(1);
58
53
  }
59
54
  } catch (error) {
@@ -126,11 +121,7 @@ export async function syncCommand(options: SyncOptions) {
126
121
  process.exit(1);
127
122
  }
128
123
 
129
- const spinner = ora({
130
- text: '正在同步数据库表...',
131
- color: 'cyan',
132
- spinner: 'dots'
133
- }).start();
124
+ Logger.info('正在同步数据库表...');
134
125
 
135
126
  const args = ['run', syncScript];
136
127
 
@@ -160,9 +151,9 @@ export async function syncCommand(options: SyncOptions) {
160
151
  await proc.exited;
161
152
 
162
153
  if (proc.exitCode === 0) {
163
- spinner.succeed('数据库同步完成');
154
+ Logger.success('数据库同步完成');
164
155
  } else {
165
- spinner.fail('数据库同步失败');
156
+ Logger.error('数据库同步失败');
166
157
  process.exit(1);
167
158
  }
168
159
  } catch (error) {
@@ -172,70 +163,7 @@ export async function syncCommand(options: SyncOptions) {
172
163
  }
173
164
  }
174
165
 
175
- // ========== Addon 命令 ==========
176
- export const addonCommand = {
177
- async install(name: string, options: { source?: string }) {
178
- const spinner = ora({
179
- text: `正在安装插件: ${name}`,
180
- color: 'cyan',
181
- spinner: 'dots'
182
- }).start();
183
-
184
- try {
185
- // TODO: 实现插件安装逻辑
186
- // 1. 从 source 或默认源下载插件
187
- // 2. 解压到 addons 目录
188
- // 3. 安装插件依赖
189
- // 4. 执行插件安装脚本
190
-
191
- spinner.succeed(`插件 ${name} 安装成功`);
192
- } catch (error) {
193
- spinner.fail(`插件 ${name} 安装失败`);
194
- throw error;
195
- }
196
- },
197
-
198
- async uninstall(name: string, options: { keepData: boolean }) {
199
- const spinner = ora({
200
- text: `正在卸载插件: ${name}`,
201
- color: 'cyan',
202
- spinner: 'dots'
203
- }).start();
204
-
205
- try {
206
- // TODO: 实现插件卸载逻辑
207
- // 1. 执行插件卸载脚本
208
- // 2. 删除插件文件
209
- // 3. 可选:删除插件数据
210
-
211
- spinner.succeed(`插件 ${name} 卸载成功`);
212
- } catch (error) {
213
- spinner.fail(`插件 ${name} 卸载失败`);
214
- throw error;
215
- }
216
- },
217
-
218
- async list() {
219
- try {
220
- const projectRoot = getProjectRoot();
221
- const addonsDir = join(projectRoot, 'addons');
222
-
223
- if (!existsSync(addonsDir)) {
224
- Logger.info('未找到 addons 目录');
225
- return;
226
- }
227
-
228
- // TODO: 读取已安装的插件列表
229
- Logger.info('已安装的插件:\n');
230
- Logger.info('(功能开发中)');
231
- } catch (error) {
232
- Logger.error('获取插件列表失败:');
233
- console.error(error);
234
- }
235
- }
236
- };
237
-
238
- // ========== 导出新增的同步命令 ==========
166
+ // ========== 导出同步命令 ==========
239
167
  export { syncApiCommand } from './syncApi.js';
240
168
  export { syncMenuCommand } from './syncMenu.js';
241
169
  export { syncDevCommand } from './syncDev.js';
@@ -111,17 +111,17 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
111
111
  const apis: ApiInfo[] = [];
112
112
 
113
113
  // 1. 扫描 Core 框架 API
114
- Logger.info('=== 扫描 Core 框架 API (core/apis) ===');
114
+ Logger.debug('=== 扫描 Core 框架 API (core/apis) ===');
115
115
  const coreApisDir = join(dirname(projectRoot), 'core', 'apis');
116
116
  try {
117
117
  const coreApiFiles = scanTsFiles(coreApisDir);
118
- Logger.info(` 找到 ${coreApiFiles.length} 个核心 API 文件`);
118
+ Logger.debug(` 找到 ${coreApiFiles.length} 个核心 API 文件`);
119
119
 
120
120
  for (const filePath of coreApiFiles) {
121
121
  const apiInfo = await extractApiInfo(filePath, coreApisDir, 'core', '', '核心接口');
122
122
  if (apiInfo) {
123
123
  apis.push(apiInfo);
124
- Logger.info(` └ ${apiInfo.path} - ${apiInfo.name}`);
124
+ Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
125
125
  }
126
126
  }
127
127
 
@@ -129,13 +129,13 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
129
129
  Logger.info('\n=== 扫描项目 API (apis) ===');
130
130
  const projectApisDir = join(projectRoot, 'apis');
131
131
  const projectApiFiles = scanTsFiles(projectApisDir);
132
- Logger.info(` 找到 ${projectApiFiles.length} 个项目 API 文件`);
132
+ Logger.debug(` 找到 ${projectApiFiles.length} 个项目 API 文件`);
133
133
 
134
134
  for (const filePath of projectApiFiles) {
135
135
  const apiInfo = await extractApiInfo(filePath, projectApisDir, 'app', '', '项目接口');
136
136
  if (apiInfo) {
137
137
  apis.push(apiInfo);
138
- Logger.info(` └ ${apiInfo.path} - ${apiInfo.name}`);
138
+ Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
139
139
  }
140
140
  }
141
141
 
@@ -148,7 +148,7 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
148
148
 
149
149
  // 检查 apis 子目录是否存在
150
150
  if (!addonDirExists(addonName, 'apis')) {
151
- Logger.info(` [${addonName}] 无 apis 目录,跳过`);
151
+ Logger.debug(` [${addonName}] 无 apis 目录,跳过`);
152
152
  continue;
153
153
  }
154
154
 
@@ -166,13 +166,13 @@ async function scanAllApis(projectRoot: string): Promise<ApiInfo[]> {
166
166
  }
167
167
 
168
168
  const addonApiFiles = scanTsFiles(addonApisDir);
169
- Logger.info(` [${addonName}] 找到 ${addonApiFiles.length} 个 API 文件`);
169
+ Logger.debug(` [${addonName}] 找到 ${addonApiFiles.length} 个 API 文件`);
170
170
 
171
171
  for (const filePath of addonApiFiles) {
172
172
  const apiInfo = await extractApiInfo(filePath, addonApisDir, 'addon', addonName, addonTitle);
173
173
  if (apiInfo) {
174
174
  apis.push(apiInfo);
175
- Logger.info(` └ ${apiInfo.path} - ${apiInfo.name}`);
175
+ Logger.debug(` └ ${apiInfo.path} - ${apiInfo.name}`);
176
176
  }
177
177
  }
178
178
  }
@@ -209,7 +209,7 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
209
209
  }
210
210
  });
211
211
  stats.updated++;
212
- Logger.info(` └ 更新接口: ${api.name} (ID: ${existing.id}, Path: ${api.path})`);
212
+ Logger.debug(` └ 更新接口: ${api.name} (ID: ${existing.id}, Path: ${api.path})`);
213
213
  } else {
214
214
  const id = await helper.insData({
215
215
  table: 'core_api',
@@ -223,7 +223,7 @@ async function syncApis(helper: any, apis: ApiInfo[]): Promise<{ created: number
223
223
  }
224
224
  });
225
225
  stats.created++;
226
- Logger.info(` └ 新增接口: ${api.name} (ID: ${id}, Path: ${api.path})`);
226
+ Logger.debug(` └ 新增接口: ${api.name} (ID: ${id}, Path: ${api.path})`);
227
227
  }
228
228
  } catch (error: any) {
229
229
  Logger.error(`同步接口 "${api.name}" 失败:`, error);
@@ -253,7 +253,7 @@ async function deleteObsoleteRecords(helper: any, apiPaths: Set<string>): Promis
253
253
  where: { id: record.id }
254
254
  });
255
255
  deletedCount++;
256
- Logger.info(` └ 删除记录: ${record.name} (ID: ${record.id}, path: ${record.path})`);
256
+ Logger.debug(` └ 删除记录: ${record.name} (ID: ${record.id}, path: ${record.path})`);
257
257
  }
258
258
  }
259
259
 
@@ -289,7 +289,7 @@ export async function syncApiCommand(options: SyncApiOptions = {}) {
289
289
  const helper = Database.getDbHelper();
290
290
 
291
291
  // 1. 检查表是否存在
292
- Logger.info('=== 检查数据表 ===');
292
+ Logger.debug('=== 检查数据表 ===');
293
293
  const exists = await helper.tableExists('core_api');
294
294
 
295
295
  if (!exists) {
@@ -300,13 +300,13 @@ export async function syncApiCommand(options: SyncApiOptions = {}) {
300
300
  Logger.info(`✅ 表 core_api 存在\n`);
301
301
 
302
302
  // 2. 扫描所有 API 文件
303
- Logger.info('=== 步骤 2: 扫描 API 文件 ===');
303
+ Logger.debug('=== 步骤 2: 扫描 API 文件 ===');
304
304
  const apis = await scanAllApis(projectRoot);
305
305
  const apiPaths = new Set(apis.map((api) => api.path));
306
306
  Logger.info(`\n✅ 共扫描到 ${apis.length} 个 API 接口\n`);
307
307
 
308
308
  // 3. 同步 API 数据
309
- Logger.info('=== 步骤 3: 同步 API 数据(新增/更新) ===');
309
+ Logger.debug('=== 步骤 3: 同步 API 数据(新增/更新) ===');
310
310
  const stats = await syncApis(helper, apis);
311
311
 
312
312
  // 4. 删除文件中不存在的接口
@@ -5,7 +5,6 @@
5
5
  import { Command } from 'commander';
6
6
  import { join } from 'pathe';
7
7
  import { existsSync } from 'node:fs';
8
- import ora from 'ora';
9
8
  import { Logger } from '../lib/logger.js';
10
9
  import { SyncDb } from './syncDb/index.js';
11
10
 
@@ -71,7 +71,7 @@ export async function syncDevCommand(options: SyncDevOptions = {}) {
71
71
  }
72
72
 
73
73
  const menuIds = allMenus.length > 0 ? allMenus.map((m: any) => m.id).join(',') : '';
74
- Logger.info(`查询到 ${allMenus.length} 个菜单,ID 列表: ${menuIds || '(空)'}`);
74
+ Logger.debug(`查询到 ${allMenus.length} 个菜单,ID 列表: ${menuIds || '(空)'}`);
75
75
 
76
76
  // 查询所有接口 ID
77
77
  const existApi = await helper.tableExists('core_api');
@@ -84,7 +84,7 @@ export async function syncDevCommand(options: SyncDevOptions = {}) {
84
84
 
85
85
  if (allApis && Array.isArray(allApis) && allApis.length > 0) {
86
86
  apiIds = allApis.map((a: any) => a.id).join(',');
87
- Logger.info(`查询到 ${allApis.length} 个接口,ID 列表: ${apiIds}`);
87
+ Logger.debug(`查询到 ${allApis.length} 个接口,ID 列表: ${apiIds}`);
88
88
  } else {
89
89
  Logger.info('未查询到接口数据');
90
90
  }
@@ -212,8 +212,8 @@ export async function syncDevCommand(options: SyncDevOptions = {}) {
212
212
  // 先删除旧数据
213
213
  await redis.del(redisKey);
214
214
 
215
- // 批量添加到 Set
216
- const result = await redis.sadd(redisKey, roleApiPaths);
215
+ // 批量添加到 Set(使用扩展运算符展开数组)
216
+ const result = await redis.sadd(redisKey, ...roleApiPaths);
217
217
 
218
218
  if (result > 0) {
219
219
  cachedRoles++;
@@ -176,7 +176,7 @@ async function syncMenus(helper: any, menus: MenuConfig[]): Promise<{ created: n
176
176
  });
177
177
  parentId = existingParent.id;
178
178
  stats.updated++;
179
- Logger.info(` └ 更新父级菜单: ${menu.name} (ID: ${parentId}, Path: ${menu.path})`);
179
+ Logger.debug(` └ 更新父级菜单: ${menu.name} (ID: ${parentId}, Path: ${menu.path})`);
180
180
  } else {
181
181
  parentId = await helper.insData({
182
182
  table: 'core_menu',
@@ -190,7 +190,7 @@ async function syncMenus(helper: any, menus: MenuConfig[]): Promise<{ created: n
190
190
  }
191
191
  });
192
192
  stats.created++;
193
- Logger.info(` └ 新增父级菜单: ${menu.name} (ID: ${parentId}, Path: ${menu.path})`);
193
+ Logger.debug(` └ 新增父级菜单: ${menu.name} (ID: ${parentId}, Path: ${menu.path})`);
194
194
  }
195
195
 
196
196
  // 2. 同步子级菜单(自动追加父级路径前缀)
@@ -217,7 +217,7 @@ async function syncMenus(helper: any, menus: MenuConfig[]): Promise<{ created: n
217
217
  }
218
218
  });
219
219
  stats.updated++;
220
- Logger.info(` └ 更新子级菜单: ${child.name} (ID: ${existingChild.id}, PID: ${parentId}, Path: ${childFullPath})`);
220
+ Logger.debug(` └ 更新子级菜单: ${child.name} (ID: ${existingChild.id}, PID: ${parentId}, Path: ${childFullPath})`);
221
221
  } else {
222
222
  const childId = await helper.insData({
223
223
  table: 'core_menu',
@@ -231,7 +231,7 @@ async function syncMenus(helper: any, menus: MenuConfig[]): Promise<{ created: n
231
231
  }
232
232
  });
233
233
  stats.created++;
234
- Logger.info(` └ 新增子级菜单: ${child.name} (ID: ${childId}, PID: ${parentId}, Path: ${childFullPath})`);
234
+ Logger.debug(` └ 新增子级菜单: ${child.name} (ID: ${childId}, PID: ${parentId}, Path: ${childFullPath})`);
235
235
  }
236
236
  }
237
237
  }
@@ -248,7 +248,7 @@ async function syncMenus(helper: any, menus: MenuConfig[]): Promise<{ created: n
248
248
  * 删除配置中不存在的菜单(强制删除)
249
249
  */
250
250
  async function deleteObsoleteRecords(helper: any, configPaths: Set<string>): Promise<number> {
251
- Logger.info(`\n=== 删除配置中不存在的记录 ===`);
251
+ Logger.debug(`\n=== 删除配置中不存在的记录 ===`);
252
252
 
253
253
  const allRecords = await helper.getAll({
254
254
  table: 'core_menu',
@@ -264,12 +264,12 @@ async function deleteObsoleteRecords(helper: any, configPaths: Set<string>): Pro
264
264
  where: { id: record.id }
265
265
  });
266
266
  deletedCount++;
267
- Logger.info(` └ 删除记录: ${record.name} (ID: ${record.id}, path: ${record.path})`);
267
+ Logger.debug(` └ 删除记录: ${record.name} (ID: ${record.id}, path: ${record.path})`);
268
268
  }
269
269
  }
270
270
 
271
271
  if (deletedCount === 0) {
272
- Logger.info(' ✅ 无需删除的记录');
272
+ Logger.debug(' ✅ 无需删除的记录');
273
273
  }
274
274
 
275
275
  return deletedCount;
@@ -295,7 +295,7 @@ export async function syncMenuCommand(options: SyncMenuOptions = {}) {
295
295
  Logger.info('开始同步菜单配置到数据库...\n');
296
296
 
297
297
  // 1. 读取两个配置文件
298
- Logger.info('=== 步骤 1: 读取菜单配置文件 ===');
298
+ Logger.debug('=== 步骤 1: 读取菜单配置文件 ===');
299
299
  const projectMenuPath = join(projectDir, 'menu.json');
300
300
  const coreMenuPath = join(coreDir, 'menu.json');
301
301
 
@@ -316,7 +316,7 @@ export async function syncMenuCommand(options: SyncMenuOptions = {}) {
316
316
  // 打印合并后的菜单结构
317
317
  for (const menu of mergedMenus) {
318
318
  const childCount = menu.children?.length || 0;
319
- Logger.info(` └ ${menu.name} (${menu.path}) - ${childCount} 个子菜单`);
319
+ Logger.debug(` └ ${menu.name} (${menu.path}) - ${childCount} 个子菜单`);
320
320
  }
321
321
 
322
322
  // 连接数据库(SQL + Redis)
@@ -325,7 +325,7 @@ export async function syncMenuCommand(options: SyncMenuOptions = {}) {
325
325
  const helper = Database.getDbHelper();
326
326
 
327
327
  // 3. 检查表是否存在
328
- Logger.info('\n=== 步骤 3: 检查数据表 ===');
328
+ Logger.debug('\n=== 步骤 3: 检查数据表 ===');
329
329
  const exists = await helper.tableExists('core_menu');
330
330
 
331
331
  if (!exists) {
@@ -333,22 +333,22 @@ export async function syncMenuCommand(options: SyncMenuOptions = {}) {
333
333
  process.exit(1);
334
334
  }
335
335
 
336
- Logger.info(`✅ 表 core_menu 存在`);
336
+ Logger.debug(`✅ 表 core_menu 存在`);
337
337
 
338
338
  // 4. 收集配置文件中所有菜单的 path
339
- Logger.info('\n=== 步骤 4: 收集配置菜单路径 ===');
339
+ Logger.debug('\n=== 步骤 4: 收集配置菜单路径 ===');
340
340
  const configPaths = collectPaths(mergedMenus);
341
- Logger.info(`✅ 配置文件中共有 ${configPaths.size} 个菜单路径`);
341
+ Logger.debug(`✅ 配置文件中共有 ${configPaths.size} 个菜单路径`);
342
342
 
343
343
  // 5. 同步菜单
344
- Logger.info('\n=== 步骤 5: 同步菜单数据(新增/更新) ===');
344
+ Logger.debug('\n=== 步骤 5: 同步菜单数据(新增/更新) ===');
345
345
  const stats = await syncMenus(helper, mergedMenus);
346
346
 
347
347
  // 6. 删除文件中不存在的菜单(强制删除)
348
348
  const deletedCount = await deleteObsoleteRecords(helper, configPaths);
349
349
 
350
350
  // 7. 构建树形结构预览
351
- Logger.info('\n=== 步骤 7: 菜单结构预览 ===');
351
+ Logger.debug('\n=== 步骤 7: 菜单结构预览 ===');
352
352
  const allMenus = await helper.getAll({
353
353
  table: 'core_menu',
354
354
  fields: ['id', 'pid', 'name', 'path', 'type'],
@@ -358,9 +358,9 @@ export async function syncMenuCommand(options: SyncMenuOptions = {}) {
358
358
  const parentMenus = allMenus.filter((m: any) => m.pid === 0);
359
359
  for (const parent of parentMenus) {
360
360
  const children = allMenus.filter((m: any) => m.pid === parent.id);
361
- Logger.info(` └ ${parent.name} (${parent.path})`);
361
+ Logger.debug(` └ ${parent.name} (${parent.path})`);
362
362
  for (const child of children) {
363
- Logger.info(` └ ${child.name} (${child.path})`);
363
+ Logger.debug(` └ ${child.name} (${child.path})`);
364
364
  }
365
365
  }
366
366
 
package/lib/middleware.ts CHANGED
@@ -58,40 +58,12 @@ export interface CorsResult {
58
58
  * @returns CORS 配置对象
59
59
  */
60
60
  export const setCorsOptions = (req: Request): CorsResult => {
61
- const requestOrigin = req.headers.get('origin');
62
- let allowedOrigin = '*';
63
-
64
- // 如果配置了 CORS_ALLOWED_ORIGIN
65
- if (Env.CORS_ALLOWED_ORIGIN) {
66
- // 如果配置为 *,使用请求的 origin(而不是返回 *)
67
- if (Env.CORS_ALLOWED_ORIGIN === '*') {
68
- allowedOrigin = requestOrigin || '*';
69
- } else {
70
- // 支持多个源,用逗号分隔
71
- const allowedOrigins = Env.CORS_ALLOWED_ORIGIN.split(',').map((origin) => origin.trim());
72
-
73
- // 如果请求的 origin 在允许列表中,返回该 origin
74
- if (requestOrigin && allowedOrigins.includes(requestOrigin)) {
75
- allowedOrigin = requestOrigin;
76
- } else if (allowedOrigins.length === 1) {
77
- // 如果只配置了一个源,直接使用
78
- allowedOrigin = allowedOrigins[0];
79
- } else {
80
- // 多个源但请求源不在列表中,不允许跨域
81
- allowedOrigin = 'null';
82
- }
83
- }
84
- } else if (requestOrigin) {
85
- // 没有配置 CORS_ALLOWED_ORIGIN,使用请求的 origin
86
- allowedOrigin = requestOrigin;
87
- }
88
-
89
61
  return {
90
62
  headers: {
91
- 'Access-Control-Allow-Origin': allowedOrigin,
92
- 'Access-Control-Allow-Methods': Env.CORS_ALLOWED_METHODS || 'GET, POST, PUT, DELETE, OPTIONS',
93
- 'Access-Control-Allow-Headers': Env.CORS_ALLOWED_HEADERS || 'Content-Type, Authorization, authorization, token',
94
- 'Access-Control-Expose-Headers': Env.CORS_EXPOSE_HEADERS || 'Content-Range, X-Content-Range, Authorization, authorization, token',
63
+ 'Access-Control-Allow-Origin': Env.CORS_ALLOWED_ORIGIN === '*' ? req.headers.get('origin') : Env.CORS_ALLOWED_ORIGIN,
64
+ 'Access-Control-Allow-Methods': Env.CORS_ALLOWED_METHODS,
65
+ 'Access-Control-Allow-Headers': Env.CORS_ALLOWED_HEADERS,
66
+ 'Access-Control-Expose-Headers': Env.CORS_EXPOSE_HEADERS,
95
67
  'Access-Control-Max-Age': Env.CORS_MAX_AGE || 86400,
96
68
  'Access-Control-Allow-Credentials': Env.CORS_ALLOW_CREDENTIALS || 'true'
97
69
  }
package/main.ts CHANGED
@@ -8,6 +8,7 @@ import { Yes, No } from './util.js';
8
8
  import { Logger } from './lib/logger.js';
9
9
  import { Cipher } from './lib/cipher.js';
10
10
  import { Jwt } from './lib/jwt.js';
11
+ import { Database } from './lib/database.js';
11
12
  import { Lifecycle } from './lifecycle/lifecycle.js';
12
13
 
13
14
  import type { Server } from 'bun';
@@ -45,7 +46,6 @@ export class Befly {
45
46
 
46
47
  // 2. 关闭数据库连接
47
48
  try {
48
- const { Database } = await import('./lib/database.js');
49
49
  await Database.disconnect();
50
50
  Logger.info('✅ 数据库连接已关闭');
51
51
  } catch (error: any) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.4.16",
3
+ "version": "3.5.1",
4
4
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -78,8 +78,7 @@
78
78
  "commander": "^14.0.2",
79
79
  "es-toolkit": "^1.41.0",
80
80
  "inquirer": "^12.10.0",
81
- "ora": "^9.0.0",
82
81
  "pathe": "^2.0.3"
83
82
  },
84
- "gitHead": "e1533f0a123ef756790fad4fc34dd9690a30f72e"
83
+ "gitHead": "bb6847f91fb09704ec47fdae750b3296419d5085"
85
84
  }
package/router/api.ts CHANGED
@@ -21,7 +21,6 @@ import type { BeflyContext } from '../types/befly.js';
21
21
  export function apiHandler(apiRoutes: Map<string, ApiRoute>, pluginLists: Plugin[], appContext: BeflyContext) {
22
22
  return async (req: Request): Promise<Response> => {
23
23
  const corsOptions = setCorsOptions(req);
24
- console.log('🔥[ corsOptions ]-24', corsOptions);
25
24
  let ctx: RequestContext | null = null;
26
25
  let api: ApiRoute | undefined;
27
26
  let apiPath = '';
@@ -118,37 +117,7 @@ export function apiHandler(apiRoutes: Map<string, ApiRoute>, pluginLists: Plugin
118
117
  // 记录详细的错误日志
119
118
  Logger.warn(api ? `接口 [${api.name}] 执行失败` : '处理接口请求时发生错误', error);
120
119
 
121
- // 根据错误类型返回不同的错误信息
122
- let errorMessage = '内部服务器错误';
123
- let errorDetail = {};
124
-
125
- // 数据库错误
126
- if (error.message?.includes('ECONNREFUSED') || error.message?.includes('database')) {
127
- errorMessage = '数据库连接失败';
128
- }
129
- // Redis错误
130
- else if (error.message?.includes('Redis') || error.message?.includes('redis')) {
131
- errorMessage = 'Redis服务异常';
132
- }
133
- // 权限错误
134
- else if (error.message?.includes('permission') || error.message?.includes('权限')) {
135
- errorMessage = '权限不足';
136
- }
137
- // 认证错误
138
- else if (error.message?.includes('token') || error.message?.includes('认证')) {
139
- errorMessage = '认证失败';
140
- }
141
-
142
- // 开发环境返回详细错误信息
143
- if (Env.NODE_ENV === 'development') {
144
- errorDetail = {
145
- type: error.constructor?.name || 'Error',
146
- message: error.message,
147
- stack: error.stack
148
- };
149
- }
150
-
151
- return Response.json(No(errorMessage, errorDetail), {
120
+ return Response.json(No('内部服务器错误'), {
152
121
  headers: corsOptions.headers
153
122
  });
154
123
  }