befly 3.8.25 → 3.8.27

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.
Files changed (61) hide show
  1. package/config.ts +8 -9
  2. package/hooks/{rateLimit.ts → _rateLimit.ts} +7 -13
  3. package/hooks/auth.ts +3 -11
  4. package/hooks/cors.ts +1 -4
  5. package/hooks/parser.ts +6 -8
  6. package/hooks/permission.ts +9 -12
  7. package/hooks/validator.ts +6 -9
  8. package/lib/cacheHelper.ts +0 -4
  9. package/lib/{database.ts → connect.ts} +65 -18
  10. package/lib/logger.ts +1 -17
  11. package/lib/redisHelper.ts +6 -5
  12. package/loader/loadApis.ts +3 -3
  13. package/loader/loadHooks.ts +15 -41
  14. package/loader/loadPlugins.ts +10 -16
  15. package/main.ts +25 -28
  16. package/package.json +3 -3
  17. package/plugins/cache.ts +2 -2
  18. package/plugins/cipher.ts +15 -0
  19. package/plugins/config.ts +16 -0
  20. package/plugins/db.ts +7 -17
  21. package/plugins/jwt.ts +15 -0
  22. package/plugins/logger.ts +1 -1
  23. package/plugins/redis.ts +4 -4
  24. package/plugins/tool.ts +50 -0
  25. package/router/api.ts +56 -42
  26. package/router/static.ts +12 -12
  27. package/sync/syncAll.ts +2 -20
  28. package/sync/syncApi.ts +7 -7
  29. package/sync/syncDb/apply.ts +1 -4
  30. package/sync/syncDb/constants.ts +3 -0
  31. package/sync/syncDb/ddl.ts +2 -1
  32. package/sync/syncDb/helpers.ts +5 -117
  33. package/sync/syncDb/sqlite.ts +1 -3
  34. package/sync/syncDb/table.ts +8 -142
  35. package/sync/syncDb/tableCreate.ts +25 -9
  36. package/sync/syncDb/types.ts +125 -0
  37. package/sync/syncDb/version.ts +0 -3
  38. package/sync/syncDb.ts +146 -6
  39. package/sync/syncDev.ts +19 -15
  40. package/sync/syncMenu.ts +87 -75
  41. package/tests/redisHelper.test.ts +15 -16
  42. package/tests/sync-connection.test.ts +189 -0
  43. package/tests/syncDb-apply.test.ts +287 -0
  44. package/tests/syncDb-constants.test.ts +150 -0
  45. package/tests/syncDb-ddl.test.ts +205 -0
  46. package/tests/syncDb-helpers.test.ts +112 -0
  47. package/tests/syncDb-schema.test.ts +178 -0
  48. package/tests/syncDb-types.test.ts +129 -0
  49. package/tsconfig.json +2 -2
  50. package/types/api.d.ts +1 -1
  51. package/types/befly.d.ts +23 -21
  52. package/types/common.d.ts +0 -29
  53. package/types/context.d.ts +8 -6
  54. package/types/hook.d.ts +3 -4
  55. package/types/plugin.d.ts +3 -0
  56. package/hooks/errorHandler.ts +0 -23
  57. package/hooks/requestId.ts +0 -24
  58. package/hooks/requestLogger.ts +0 -25
  59. package/hooks/responseFormatter.ts +0 -64
  60. package/router/root.ts +0 -56
  61. package/sync/syncDb/index.ts +0 -164
@@ -12,29 +12,24 @@ import { sortModules, scanModules } from '../util.js';
12
12
  import type { Plugin } from '../types/plugin.js';
13
13
  import type { BeflyContext } from '../types/befly.js';
14
14
 
15
- export async function loadPlugins(befly: {
16
- //
17
- pluginLists: Plugin[];
18
- appContext: BeflyContext;
19
- pluginsConfig?: Record<string, any>;
20
- }): Promise<void> {
15
+ export async function loadPlugins(config: Record<string, any> | undefined, plugins: Plugin[], context: BeflyContext): Promise<void> {
21
16
  try {
22
17
  const allPlugins: Plugin[] = [];
23
18
 
24
19
  // 1. 扫描核心插件
25
- const corePlugins = await scanModules<Plugin>(corePluginDir, 'core', '插件', befly.pluginsConfig);
20
+ const corePlugins = await scanModules<Plugin>(corePluginDir, 'core', '插件', config);
26
21
 
27
22
  // 2. 扫描组件插件
28
23
  const addonPlugins: Plugin[] = [];
29
24
  const addons = scanAddons();
30
25
  for (const addon of addons) {
31
26
  const dir = getAddonDir(addon, 'plugins');
32
- const plugins = await scanModules<Plugin>(dir, 'addon', '插件', befly.pluginsConfig, addon);
27
+ const plugins = await scanModules<Plugin>(dir, 'addon', '插件', config, addon);
33
28
  addonPlugins.push(...plugins);
34
29
  }
35
30
 
36
31
  // 3. 扫描项目插件
37
- const appPlugins = await scanModules<Plugin>(projectPluginDir, 'app', '插件', befly.pluginsConfig);
32
+ const appPlugins = await scanModules<Plugin>(projectPluginDir, 'app', '插件', config);
38
33
 
39
34
  // 4. 合并所有插件
40
35
  allPlugins.push(...corePlugins);
@@ -42,7 +37,7 @@ export async function loadPlugins(befly: {
42
37
  allPlugins.push(...appPlugins);
43
38
 
44
39
  // 5. 过滤禁用的插件
45
- const disablePlugins = (befly as any).config?.disablePlugins || [];
40
+ const disablePlugins = (config as any)?.disablePlugins || [];
46
41
  const enabledPlugins = allPlugins.filter((plugin) => !disablePlugins.includes(plugin.name));
47
42
 
48
43
  if (disablePlugins.length > 0) {
@@ -58,13 +53,12 @@ export async function loadPlugins(befly: {
58
53
 
59
54
  for (const plugin of sortedPlugins) {
60
55
  try {
61
- befly.pluginLists.push(plugin);
56
+ plugins.push(plugin);
62
57
 
63
- if (typeof plugin.handler === 'function') {
64
- befly.appContext[plugin.name!] = await plugin.handler(befly.appContext);
65
- } else {
66
- befly.appContext[plugin.name!] = {};
67
- }
58
+ const pluginInstance = typeof plugin.handler === 'function' ? await plugin.handler(context, config) : {};
59
+
60
+ // 直接挂载到 befly 下
61
+ (context as any)[plugin.name!] = pluginInstance;
68
62
  } catch (error: any) {
69
63
  Logger.error(`插件 ${plugin.name} 初始化失败`, error);
70
64
  process.exit(1);
package/main.ts CHANGED
@@ -10,13 +10,12 @@ import { calcPerfTime } from 'befly-util';
10
10
  import { Logger } from './lib/logger.js';
11
11
  import { Cipher } from './lib/cipher.js';
12
12
  import { Jwt } from './lib/jwt.js';
13
- import { Database } from './lib/database.js';
13
+ import { Connect } from './lib/connect.js';
14
14
  import { DbHelper } from './lib/dbHelper.js';
15
15
  import { RedisHelper } from './lib/redisHelper.js';
16
16
  import { loadPlugins } from './loader/loadPlugins.js';
17
17
  import { loadHooks } from './loader/loadHooks.js';
18
18
  import { loadApis } from './loader/loadApis.js';
19
- import { rootHandler } from './router/root.js';
20
19
  import { apiHandler } from './router/api.js';
21
20
  import { staticHandler } from './router/static.js';
22
21
  import { checkApp } from './checks/checkApp.js';
@@ -25,6 +24,7 @@ import { checkApi } from './checks/checkApi.js';
25
24
  import { syncAllCommand } from './sync/syncAll.js';
26
25
  import { coreDir } from './paths.js';
27
26
  import { defaultOptions } from './config.js';
27
+ import { isPrimaryProcess, getProcessRole } from './util.js';
28
28
 
29
29
  // ========== 类型导入 ==========
30
30
  import type { Server } from 'bun';
@@ -38,24 +38,22 @@ import type { ApiRoute } from './types/api.js';
38
38
  */
39
39
  export class Befly {
40
40
  /** API 路由映射表 */
41
- private apiRoutes: Map<string, ApiRoute> = new Map();
41
+ private apis: Map<string, ApiRoute> = new Map();
42
42
 
43
43
  /** 插件列表 */
44
- private pluginLists: Plugin[] = [];
44
+ private plugins: Plugin[] = [];
45
45
 
46
46
  /** 钩子列表 */
47
- private hookLists: Hook[] = [];
47
+ private hooks: Hook[] = [];
48
48
 
49
49
  /** 应用上下文 */
50
- public appContext: BeflyContext;
50
+ public context: BeflyContext = {};
51
51
 
52
52
  /** 最终配置(合并默认值后) */
53
- public config: BeflyOptions;
53
+ public config: BeflyOptions = { ...defaultOptions };
54
54
 
55
55
  constructor(options: BeflyOptions = {}) {
56
- this.appContext = {};
57
- // 合并配置:用户配置 > 默认配置(最多 2 级)
58
- this.config = { ...defaultOptions };
56
+ // 合并用户配置:用户配置 > 默认配置(最多 2 级)
59
57
  for (const key in options) {
60
58
  const value = options[key as keyof BeflyOptions];
61
59
  if (value !== undefined && value !== null) {
@@ -82,32 +80,27 @@ export class Befly {
82
80
  await checkApi();
83
81
 
84
82
  // 4. 加载插件
85
- await loadPlugins({
86
- pluginLists: this.pluginLists,
87
- appContext: this.appContext,
88
- pluginsConfig: this.config as any
89
- });
83
+ await loadPlugins(this.config as any, this.plugins, this.context);
90
84
 
91
85
  // 5. 加载钩子
92
- await loadHooks({
93
- hookLists: this.hookLists,
94
- pluginsConfig: this.config as any
95
- });
86
+ await loadHooks(this.config as any, this.hooks);
96
87
 
97
88
  // 6. 加载所有 API
98
- await loadApis(this.apiRoutes);
89
+ await loadApis(this.apis);
99
90
 
100
- // 7. 自动同步 (默认开启)
101
- await syncAllCommand(this.config);
91
+ // 7. 自动同步 (仅主进程执行,避免集群模式下重复执行)
92
+ if (isPrimaryProcess()) {
93
+ await syncAllCommand(this.config);
94
+ }
102
95
 
103
96
  // 8. 启动 HTTP 服务器
104
97
  const server = Bun.serve({
105
98
  port: this.config.appPort,
106
99
  hostname: this.config.appHost,
107
100
  routes: {
108
- '/': rootHandler,
109
- '/api/*': apiHandler(this.apiRoutes, this.hookLists, this.appContext),
110
- '/*': staticHandler(this.config.cors)
101
+ '/': () => Response.json({ code: 0, msg: `${this.config.appName} 接口服务已启动` }),
102
+ '/api/*': apiHandler(this.apis, this.hooks, this.context),
103
+ '/*': staticHandler(this.config)
111
104
  },
112
105
  error: (error: Error) => {
113
106
  Logger.error('服务启动时发生错误', error);
@@ -116,7 +109,11 @@ export class Befly {
116
109
  });
117
110
 
118
111
  const finalStartupTime = calcPerfTime(serverStartTime);
119
- Logger.info(`${this.config.appName} 启动成功! `);
112
+ const processRole = getProcessRole();
113
+ const roleLabel = processRole.role === 'primary' ? '主进程' : `工作进程 #${processRole.instanceId}`;
114
+ const envLabel = processRole.env === 'standalone' ? '' : ` [${processRole.env}]`;
115
+
116
+ Logger.info(`${this.config.appName} 启动成功! (${roleLabel}${envLabel})`);
120
117
  Logger.info(`服务器启动耗时: ${finalStartupTime}`);
121
118
  Logger.info(`服务器监听地址: http://${this.config.appHost}:${this.config.appPort}`);
122
119
 
@@ -128,7 +125,7 @@ export class Befly {
128
125
 
129
126
  // 关闭数据库连接
130
127
  try {
131
- await Database.disconnect();
128
+ await Connect.disconnect();
132
129
  Logger.info('数据库连接已关闭');
133
130
  } catch (error: any) {
134
131
  Logger.error('关闭数据库连接时出错:', error);
@@ -143,7 +140,7 @@ export class Befly {
143
140
 
144
141
  return server;
145
142
  } catch (error: any) {
146
- Logger.error('Befly 启动失败', error);
143
+ Logger.error('项目启动失败', error);
147
144
  process.exit(1);
148
145
  }
149
146
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.8.25",
3
+ "version": "3.8.27",
4
4
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -66,12 +66,12 @@
66
66
  "bun": ">=1.3.0"
67
67
  },
68
68
  "dependencies": {
69
- "befly-util": "^1.0.4",
69
+ "befly-util": "^1.0.6",
70
70
  "chalk": "^5.6.2",
71
71
  "es-toolkit": "^1.41.0",
72
72
  "pathe": "^2.0.3"
73
73
  },
74
- "gitHead": "998b9fd60b5f183796eaac89a47c2d5374aa308a",
74
+ "gitHead": "54c0f11f65a56f7df036fdf386b72329496777b4",
75
75
  "devDependencies": {
76
76
  "typescript": "^5.9.3"
77
77
  }
package/plugins/cache.ts CHANGED
@@ -11,8 +11,8 @@ import type { BeflyContext } from '../types/befly.js';
11
11
  * 缓存插件
12
12
  */
13
13
  const cachePlugin: Plugin = {
14
- after: ['db', 'redis'],
15
- async onInit(befly: BeflyContext): Promise<CacheHelper> {
14
+ after: [],
15
+ async handler(befly: BeflyContext): Promise<CacheHelper> {
16
16
  return new CacheHelper(befly);
17
17
  }
18
18
  };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Cipher 插件
3
+ * 提供加密解密功能
4
+ */
5
+
6
+ import { Cipher } from '../lib/cipher.js';
7
+
8
+ import type { Plugin } from '../types/plugin.js';
9
+
10
+ export default {
11
+ name: 'cipher',
12
+ handler: (context, config) => {
13
+ return Cipher;
14
+ }
15
+ } as Plugin;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 配置插件
3
+ * 提供访问项目配置的能力
4
+ */
5
+
6
+ // 类型导入
7
+ import type { Plugin } from '../types/plugin.js';
8
+
9
+ const plugin: Plugin = {
10
+ handler: (context, config) => {
11
+ // 直接返回第二个参数中的配置
12
+ return config || {};
13
+ }
14
+ };
15
+
16
+ export default plugin;
package/plugins/db.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { Logger } from '../lib/logger.js';
7
- import { Database } from '../lib/database.js';
7
+ import { Connect } from '../lib/connect.js';
8
8
  import { DbHelper } from '../lib/dbHelper.js';
9
9
  import type { Plugin } from '../types/plugin.js';
10
10
  import type { BeflyContext } from '../types/befly.js';
@@ -13,28 +13,18 @@ import type { BeflyContext } from '../types/befly.js';
13
13
  * 数据库插件
14
14
  */
15
15
  const dbPlugin: Plugin = {
16
- after: ['redis'],
17
- async onInit(this: Plugin, befly: BeflyContext): Promise<DbHelper | Record<string, never>> {
16
+ after: ['logger'],
17
+ async handler(this: Plugin, befly: BeflyContext): Promise<DbHelper> {
18
18
  let sql: any = null;
19
19
  const config = this.config || {};
20
20
 
21
21
  try {
22
- // 默认启用,除非显式禁用
23
- if (config.enable !== 0) {
24
- // 创建 Bun SQL 客户端(内置连接池),并确保连接验证成功后再继续
25
- // 从配置读取连接超时配置
26
- // const connectionTimeout = config.connectionTimeout ? parseInt(config.connectionTimeout) : 30000;
22
+ sql = await Connect.connectSql(config);
27
23
 
28
- sql = await Database.connectSql(config);
24
+ // 创建数据库管理器实例,直接传入 sql 对象
25
+ const dbManager = new DbHelper(befly, sql);
29
26
 
30
- // 创建数据库管理器实例,直接传入 sql 对象
31
- const dbManager = new DbHelper(befly, sql);
32
-
33
- return dbManager;
34
- } else {
35
- Logger.warn('数据库未启用,跳过初始化');
36
- return {};
37
- }
27
+ return dbManager;
38
28
  } catch (error: any) {
39
29
  Logger.error('数据库初始化失败', error);
40
30
 
package/plugins/jwt.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * JWT 插件
3
+ * 提供 JSON Web Token 签名和验证功能
4
+ */
5
+
6
+ import { Jwt } from '../lib/jwt.js';
7
+
8
+ import type { Plugin } from '../types/plugin.js';
9
+
10
+ export default {
11
+ name: 'jwt',
12
+ handler: (context, config) => {
13
+ return Jwt;
14
+ }
15
+ } as Plugin;
package/plugins/logger.ts CHANGED
@@ -12,7 +12,7 @@ import type { BeflyContext } from '../types/befly.js';
12
12
  */
13
13
  const loggerPlugin: Plugin = {
14
14
  after: [],
15
- async onInit(this: Plugin, befly: BeflyContext): Promise<typeof Logger> {
15
+ async handler(this: Plugin, befly: BeflyContext): Promise<typeof Logger> {
16
16
  try {
17
17
  // 配置 Logger
18
18
  if (this.config) {
package/plugins/redis.ts CHANGED
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import { Logger } from '../lib/logger.js';
7
+ import { Connect } from '../lib/connect.js';
7
8
  import { RedisHelper } from '../lib/redisHelper.js';
8
- import { Database } from '../lib/database.js';
9
9
  import type { Plugin } from '../types/plugin.js';
10
10
  import type { BeflyContext } from '../types/befly.js';
11
11
 
@@ -14,14 +14,14 @@ import type { BeflyContext } from '../types/befly.js';
14
14
  */
15
15
  const redisPlugin: Plugin = {
16
16
  after: ['logger'],
17
- async onInit(this: Plugin, befly: BeflyContext): Promise<RedisHelper | Record<string, never>> {
17
+ async handler(this: Plugin, befly: BeflyContext): Promise<RedisHelper | Record<string, never>> {
18
18
  const config = this.config || {};
19
19
  try {
20
20
  // 默认启用,除非显式禁用 (这里假设只要配置了 redis 插件就启用,或者检查 enable 字段)
21
21
  // 为了兼容性,如果 config 为空,可能意味着使用默认值连接本地 redis
22
22
 
23
- // 初始化 Redis 客户端(统一使用 database.ts 的连接管理)
24
- await Database.connectRedis(config);
23
+ // 初始化 Redis 客户端(统一使用 connect.ts 的连接管理)
24
+ await Connect.connectRedis(config);
25
25
 
26
26
  // 返回 RedisHelper 实例
27
27
  return new RedisHelper(config.prefix);
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 工具插件
3
+ * 提供常用的工具函数
4
+ */
5
+
6
+ // 类型导入
7
+ import type { Plugin } from '../types/plugin.js';
8
+
9
+ /**
10
+ * 成功响应
11
+ * @param msg - 消息
12
+ * @param data - 数据(可选)
13
+ * @param other - 其他字段(可选)
14
+ * @returns 成功响应对象
15
+ */
16
+ export function Yes(msg: string, data: any = {}, other: Record<string, any> = {}) {
17
+ return {
18
+ code: 0,
19
+ msg: msg,
20
+ data: data,
21
+ ...other
22
+ };
23
+ }
24
+
25
+ /**
26
+ * 失败响应
27
+ * @param msg - 消息
28
+ * @param data - 数据(可选)
29
+ * @param other - 其他字段(可选)
30
+ * @returns 失败响应对象
31
+ */
32
+ export function No(msg: string, data: any = null, other: Record<string, any> = {}) {
33
+ return {
34
+ code: 1,
35
+ msg: msg,
36
+ data: data,
37
+ ...other
38
+ };
39
+ }
40
+
41
+ const plugin: Plugin = {
42
+ handler: () => {
43
+ return {
44
+ Yes: Yes,
45
+ No: No
46
+ };
47
+ }
48
+ };
49
+
50
+ export default plugin;
package/router/api.ts CHANGED
@@ -3,8 +3,12 @@
3
3
  * 处理 /api/* 路径的请求
4
4
  */
5
5
 
6
+ // 外部依赖
7
+ import { genShortId } from 'befly-util';
8
+
6
9
  // 相对导入
7
- import { compose, JsonResponse } from '../util.js';
10
+ import { FinalResponse } from '../util.js';
11
+ import { Logger } from '../lib/logger.js';
8
12
 
9
13
  // 类型导入
10
14
  import type { RequestContext } from '../types/context.js';
@@ -14,72 +18,82 @@ import type { BeflyContext } from '../types/befly.js';
14
18
 
15
19
  /**
16
20
  * API处理器工厂函数
17
- * @param apiRoutes - API路由映射表
18
- * @param hookLists - 钩子列表
19
- * @param appContext - 应用上下文
21
+ * @param apis - API路由映射表
22
+ * @param hooks - 钩子列表
23
+ * @param context - 应用上下文
20
24
  */
21
- export function apiHandler(apiRoutes: Map<string, ApiRoute>, hookLists: Hook[], appContext: BeflyContext) {
22
- // 提取所有钩子的处理函数
23
- const middleware = hookLists.map((h) => h.handler);
24
-
25
- // 组合钩子链
26
- const fn = compose(middleware);
27
-
25
+ export function apiHandler(apis: Map<string, ApiRoute>, hooks: Hook[], context: BeflyContext) {
28
26
  return async (req: Request): Promise<Response> => {
29
- // 1. 创建请求上下文
27
+ // 1. 生成请求 ID
28
+ const requestId = genShortId();
29
+
30
+ // 2. 创建请求上下文
30
31
  const url = new URL(req.url);
31
32
  const apiPath = `${req.method}${url.pathname}`;
33
+ const clientIp = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || req.headers.get('x-real-ip') || 'unknown';
32
34
 
33
35
  const ctx: RequestContext = {
34
36
  body: {},
35
37
  user: {},
36
38
  req: req,
37
39
  now: Date.now(),
38
- corsHeaders: {},
39
- ip: req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() || req.headers.get('x-real-ip') || 'unknown',
40
- route: apiPath
40
+ ip: clientIp,
41
+ headers: req.headers,
42
+ route: apiPath,
43
+ requestId: requestId,
44
+ corsHeaders: {
45
+ 'X-Request-ID': requestId
46
+ },
47
+ api: apis.get(apiPath),
48
+ response: undefined,
49
+ result: undefined
41
50
  };
42
51
 
43
- // 2. 获取API路由
44
- const api = apiRoutes.get(apiPath);
52
+ try {
53
+ // 4. 串联执行所有钩子
54
+ for (const hook of hooks) {
55
+ await hook.handler(context, ctx);
45
56
 
46
- // 注意:即使 api 不存在,也需要执行插件链(以便处理 CORS OPTIONS 请求或 404 响应)
47
- // 如果是 OPTIONS 请求,通常不需要 api 对象
48
- if (api) {
49
- ctx.api = api;
50
- }
57
+ // 如果钩子已经设置了 response,停止执行
58
+ if (ctx.response) {
59
+ return ctx.response;
60
+ }
61
+ }
51
62
 
52
- // 3. 执行插件链(洋葱模型)
53
- // 错误处理已由 errorHandler 插件接管
54
- await fn(appContext, ctx, async () => {
55
- // 核心执行器:执行 API handler
56
- // 如果没有找到 API 且没有被前面的插件拦截(如 CORS),则返回 404
63
+ // 5. 执行 API handler
57
64
  if (!ctx.api) {
58
- // 只有非 OPTIONS 请求才报 404(OPTIONS 请求通常由 cors 插件处理并返回)
59
65
  if (req.method !== 'OPTIONS') {
60
- ctx.response = JsonResponse(ctx, '接口不存在');
66
+ ctx.response = Response.json(
67
+ {
68
+ code: 1,
69
+ msg: '接口不存在'
70
+ },
71
+ {
72
+ headers: ctx.corsHeaders
73
+ }
74
+ );
61
75
  }
62
- return;
63
- }
64
-
65
- if (ctx.api.handler) {
66
- const result = await ctx.api.handler(appContext, ctx, req);
76
+ } else if (ctx.api.handler) {
77
+ const result = await ctx.api.handler(context, ctx);
67
78
 
68
79
  if (result instanceof Response) {
69
80
  ctx.response = result;
70
81
  } else {
71
- // 将结果存入 ctx.result,由 responseFormatter 插件统一处理
72
82
  ctx.result = result;
73
83
  }
74
84
  }
75
- });
76
85
 
77
- // 4. 返回响应
78
- if (ctx.response) {
79
- return ctx.response;
86
+ // 6. 返回响应(自动处理 response/result/日志)
87
+ return FinalResponse(ctx);
88
+ } catch (err: any) {
89
+ // 全局错误处理
90
+ const errorPath = ctx.api ? apiPath : req.url;
91
+ Logger.error(`请求错误: ${errorPath}`, err);
92
+ ctx.result = {
93
+ code: 1,
94
+ msg: '内部服务错误'
95
+ };
96
+ return FinalResponse(ctx);
80
97
  }
81
-
82
- // 兜底响应(理论上不应执行到这里,responseFormatter 会处理)
83
- return JsonResponse(ctx, 'No response generated');
84
98
  };
85
99
  }
package/router/static.ts CHANGED
@@ -12,16 +12,16 @@ import { Logger } from '../lib/logger.js';
12
12
  import { setCorsOptions } from '../util.js';
13
13
 
14
14
  // 类型导入
15
- import type { CorsConfig } from '../types/befly.js';
15
+ import type { BeflyOptions } from '../types/befly.js';
16
16
 
17
17
  /**
18
18
  * 静态文件处理器工厂
19
- * @param corsConfig - CORS 配置
19
+ * @param config - Befly 配置
20
20
  */
21
- export function staticHandler(corsConfig: CorsConfig = {}) {
21
+ export function staticHandler(config: BeflyOptions) {
22
22
  return async (req: Request): Promise<Response> => {
23
23
  // 设置 CORS 响应头
24
- const corsHeaders = setCorsOptions(req, corsConfig);
24
+ const corsHeaders = setCorsOptions(req, config.cors);
25
25
 
26
26
  const url = new URL(req.url);
27
27
  const filePath = join(projectDir, 'public', url.pathname);
@@ -45,9 +45,11 @@ export function staticHandler(corsConfig: CorsConfig = {}) {
45
45
  });
46
46
  } else {
47
47
  return Response.json(
48
- { code: 1, msg: '文件未找到' },
49
48
  {
50
- status: 404,
49
+ code: 1,
50
+ msg: '文件未找到'
51
+ },
52
+ {
51
53
  headers: corsHeaders
52
54
  }
53
55
  );
@@ -56,14 +58,12 @@ export function staticHandler(corsConfig: CorsConfig = {}) {
56
58
  // 记录详细的错误日志
57
59
  Logger.error('静态文件处理失败', error);
58
60
 
59
- // 根据错误类型返回不同的错误信息
60
- let errorMessage = '文件读取失败';
61
- let errorDetail = {};
62
-
63
61
  return Response.json(
64
- { code: 1, msg: errorMessage, data: errorDetail },
65
62
  {
66
- status: 500,
63
+ code: 1,
64
+ msg: '文件读取失败'
65
+ },
66
+ {
67
67
  headers: corsHeaders
68
68
  }
69
69
  );
package/sync/syncAll.ts CHANGED
@@ -16,41 +16,23 @@ export async function syncAllCommand(config: BeflyOptions, options: SyncOptions
16
16
  const startTime = Date.now();
17
17
 
18
18
  // 0. 检查项目结构
19
- Logger.debug('🔍 正在检查项目结构...');
20
- const checkResult = await checkApp();
21
- if (!checkResult) {
22
- Logger.error('项目结构检查失败,程序退出');
23
- throw new Error('项目结构检查失败');
24
- }
25
- Logger.debug(`✓ 项目结构检查完成\n`);
26
-
27
- Logger.debug('开始执行同步任务...\n');
19
+ await checkApp();
28
20
 
29
21
  // 1. 同步数据库表结构
30
- Logger.debug('📦 正在同步数据库...');
31
22
  await syncDbCommand(config, { dryRun: false, force: options.force || false });
32
- Logger.debug(`✓ 数据库同步完成\n`);
33
23
 
34
24
  // 2. 同步接口(并缓存)
35
- Logger.debug('🔌 正在同步接口...');
36
25
  await syncApiCommand(config);
37
- Logger.debug(`✓ 接口同步完成\n`);
38
26
 
39
27
  // 3. 同步菜单(并缓存)
40
- Logger.debug('📋 正在同步菜单...');
41
28
  await syncMenuCommand(config);
42
- Logger.debug(`✓ 菜单同步完成\n`);
43
29
 
44
30
  // 4. 同步开发管理员(并缓存角色权限)
45
- Logger.debug('👤 正在同步开发账号...');
46
31
  await syncDevCommand(config);
47
- Logger.debug(`✓ 开发账号同步完成\n`);
48
32
 
49
33
  // 输出总结
50
34
  const totalTimeSeconds = ((Date.now() - startTime) / 1000).toFixed(2);
51
- Logger.debug('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
52
- Logger.debug(`✅ 同步完成!总耗时: ${totalTimeSeconds} 秒`);
53
- Logger.debug('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n');
35
+ Logger.info(`同步完成 (耗时 ${totalTimeSeconds}s)`);
54
36
  } catch (error: any) {
55
37
  Logger.error('同步过程中发生错误', error);
56
38
  throw error;