befly 3.8.18 → 3.8.20

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 (50) hide show
  1. package/README.md +7 -6
  2. package/bunfig.toml +1 -1
  3. package/lib/database.ts +28 -25
  4. package/lib/dbHelper.ts +3 -3
  5. package/lib/jwt.ts +90 -99
  6. package/lib/logger.ts +44 -23
  7. package/lib/redisHelper.ts +19 -22
  8. package/lib/validator.ts +11 -4
  9. package/loader/loadApis.ts +69 -114
  10. package/loader/loadHooks.ts +65 -0
  11. package/loader/loadPlugins.ts +50 -219
  12. package/main.ts +106 -133
  13. package/package.json +15 -7
  14. package/paths.ts +20 -0
  15. package/plugins/cache.ts +1 -3
  16. package/plugins/db.ts +8 -11
  17. package/plugins/logger.ts +5 -3
  18. package/plugins/redis.ts +10 -14
  19. package/router/api.ts +60 -106
  20. package/router/root.ts +15 -12
  21. package/router/static.ts +54 -58
  22. package/sync/syncAll.ts +58 -0
  23. package/sync/syncApi.ts +264 -0
  24. package/sync/syncDb/apply.ts +194 -0
  25. package/sync/syncDb/constants.ts +76 -0
  26. package/sync/syncDb/ddl.ts +194 -0
  27. package/sync/syncDb/helpers.ts +200 -0
  28. package/sync/syncDb/index.ts +164 -0
  29. package/sync/syncDb/schema.ts +201 -0
  30. package/sync/syncDb/sqlite.ts +50 -0
  31. package/sync/syncDb/table.ts +321 -0
  32. package/sync/syncDb/tableCreate.ts +146 -0
  33. package/sync/syncDb/version.ts +72 -0
  34. package/sync/syncDb.ts +19 -0
  35. package/sync/syncDev.ts +206 -0
  36. package/sync/syncMenu.ts +331 -0
  37. package/tsconfig.json +2 -4
  38. package/types/api.d.ts +6 -0
  39. package/types/befly.d.ts +152 -28
  40. package/types/context.d.ts +29 -3
  41. package/types/hook.d.ts +35 -0
  42. package/types/index.ts +14 -1
  43. package/types/plugin.d.ts +6 -7
  44. package/types/sync.d.ts +403 -0
  45. package/check.ts +0 -378
  46. package/env.ts +0 -106
  47. package/lib/middleware.ts +0 -275
  48. package/types/env.ts +0 -65
  49. package/types/util.d.ts +0 -45
  50. package/util.ts +0 -257
@@ -1,249 +1,80 @@
1
1
  /**
2
2
  * 插件加载器
3
- * 负责扫描和初始化所有插件(核心、组件、用户)
3
+ * 负责扫描和初始化所有插件(核心、组件、项目)
4
4
  */
5
5
 
6
- import { basename } from 'pathe';
7
- import { existsSync } from 'node:fs';
8
- import { camelCase } from 'es-toolkit/string';
6
+ import { scanAddons, getAddonDir } from 'befly-util';
7
+
9
8
  import { Logger } from '../lib/logger.js';
10
- import { calcPerfTime } from '../util.js';
11
9
  import { corePluginDir, projectPluginDir } from '../paths.js';
12
- import { scanAddons, getAddonDir, addonDirExists } from '../util.js';
10
+ import { sortModules, scanModules } from '../util.js';
11
+
13
12
  import type { Plugin } from '../types/plugin.js';
14
13
  import type { BeflyContext } from '../types/befly.js';
15
14
 
16
- /**
17
- * 排序插件(根据依赖关系)
18
- */
19
- function sortPlugins(plugins: Plugin[]): Plugin[] | false {
20
- const result: Plugin[] = [];
21
- const visited = new Set<string>();
22
- const visiting = new Set<string>();
23
- const pluginMap: Record<string, Plugin> = Object.fromEntries(plugins.map((p) => [p.pluginName || p.name, p]));
24
- let isPass = true;
25
-
26
- const visit = (name: string): void => {
27
- if (visited.has(name)) return;
28
- if (visiting.has(name)) {
29
- isPass = false;
30
- return;
31
- }
32
-
33
- const plugin = pluginMap[name];
34
- if (!plugin) return;
35
-
36
- visiting.add(name);
37
- (plugin.after || []).forEach(visit);
38
- visiting.delete(name);
39
- visited.add(name);
40
- result.push(plugin);
41
- };
42
-
43
- plugins.forEach((p) => visit(p.pluginName || p.name));
44
- return isPass ? result : false;
45
- }
46
-
47
- /**
48
- * 扫描核心插件
49
- */
50
- async function scanCorePlugins(loadedPluginNames: Set<string>): Promise<Plugin[]> {
51
- const plugins: Plugin[] = [];
52
- const glob = new Bun.Glob('*.{ts,js}');
53
-
54
- for await (const file of glob.scan({
55
- cwd: corePluginDir,
56
- onlyFiles: true,
57
- absolute: true
58
- })) {
59
- if (file.endsWith('.d.ts')) continue;
60
- const fileName = basename(file).replace(/\.(ts|js)$/, '');
61
- if (fileName.startsWith('_')) continue;
62
-
63
- try {
64
- const pluginImport = await import(file);
65
- const plugin = pluginImport.default;
66
- plugin.pluginName = fileName;
67
- plugins.push(plugin);
68
- loadedPluginNames.add(fileName);
69
- } catch (err: any) {
70
- Logger.error(`核心插件 ${fileName} 导入失败`, err);
71
- process.exit(1);
72
- }
73
- }
74
-
75
- return plugins;
76
- }
77
-
78
- /**
79
- * 扫描组件插件
80
- */
81
- async function scanAddonPlugins(loadedPluginNames: Set<string>): Promise<Plugin[]> {
82
- const plugins: Plugin[] = [];
83
- const glob = new Bun.Glob('*.{ts,js}');
84
- const addons = scanAddons();
85
-
86
- for (const addon of addons) {
87
- if (!addonDirExists(addon, 'plugins')) continue;
88
-
89
- const addonPluginsDir = getAddonDir(addon, 'plugins');
90
- for await (const file of glob.scan({
91
- cwd: addonPluginsDir,
92
- onlyFiles: true,
93
- absolute: true
94
- })) {
95
- if (file.endsWith('.d.ts')) continue;
96
- const fileName = basename(file).replace(/\.(ts|js)$/, '');
97
- if (fileName.startsWith('_')) continue;
98
-
99
- const addonCamelCase = camelCase(addon);
100
- const fileNameCamelCase = camelCase(fileName);
101
- const pluginFullName = `addon${addonCamelCase.charAt(0).toUpperCase() + addonCamelCase.slice(1)}_${fileNameCamelCase}`;
102
-
103
- if (loadedPluginNames.has(pluginFullName)) {
104
- continue;
105
- }
106
-
107
- try {
108
- const normalizedFilePath = file.replace(/\\/g, '/');
109
- const pluginImport = await import(normalizedFilePath);
110
- const plugin = pluginImport.default;
111
- plugin.pluginName = pluginFullName;
112
- plugins.push(plugin);
113
- loadedPluginNames.add(pluginFullName);
114
- } catch (err: any) {
115
- Logger.error(`组件${addon} ${fileName} 导入失败`, err);
116
- process.exit(1);
117
- }
118
- }
119
- }
120
-
121
- return plugins;
122
- }
123
-
124
- /**
125
- * 扫描用户插件
126
- */
127
- async function scanUserPlugins(loadedPluginNames: Set<string>): Promise<Plugin[]> {
128
- const plugins: Plugin[] = [];
129
-
130
- if (!existsSync(projectPluginDir)) {
131
- return plugins;
132
- }
133
-
134
- const glob = new Bun.Glob('*.{ts,js}');
135
- for await (const file of glob.scan({
136
- cwd: projectPluginDir,
137
- onlyFiles: true,
138
- absolute: true
139
- })) {
140
- if (file.endsWith('.d.ts')) continue;
141
- const fileName = basename(file).replace(/\.(ts|js)$/, '');
142
- if (fileName.startsWith('_')) continue;
143
-
144
- const fileNameCamelCase = camelCase(fileName);
145
- const pluginFullName = `app${fileNameCamelCase.charAt(0).toUpperCase() + fileNameCamelCase.slice(1)}`;
146
-
147
- if (loadedPluginNames.has(pluginFullName)) {
148
- continue;
149
- }
150
-
151
- try {
152
- const normalizedFilePath = file.replace(/\\/g, '/');
153
- const pluginImport = await import(normalizedFilePath);
154
- const plugin = pluginImport.default;
155
- plugin.pluginName = pluginFullName;
156
- plugins.push(plugin);
157
- loadedPluginNames.add(pluginFullName);
158
- } catch (err: any) {
159
- Logger.error(`用户插件 ${fileName} 导入失败`, err);
160
- process.exit(1);
15
+ export async function loadPlugins(befly: {
16
+ //
17
+ pluginLists: Plugin[];
18
+ appContext: BeflyContext;
19
+ pluginsConfig?: Record<string, any>;
20
+ }): Promise<void> {
21
+ try {
22
+ const allPlugins: Plugin[] = [];
23
+
24
+ // 1. 扫描核心插件
25
+ const corePlugins = await scanModules<Plugin>(corePluginDir, 'core', '插件', befly.pluginsConfig);
26
+
27
+ // 2. 扫描组件插件
28
+ const addonPlugins: Plugin[] = [];
29
+ const addons = scanAddons();
30
+ for (const addon of addons) {
31
+ const dir = getAddonDir(addon, 'plugins');
32
+ const plugins = await scanModules<Plugin>(dir, 'addon', '插件', befly.pluginsConfig, addon);
33
+ addonPlugins.push(...plugins);
161
34
  }
162
- }
163
-
164
- return plugins;
165
- }
166
-
167
- /**
168
- * 初始化单个插件
169
- */
170
- async function initPlugin(befly: { pluginLists: Plugin[]; appContext: BeflyContext }, plugin: Plugin): Promise<void> {
171
- befly.pluginLists.push(plugin);
172
-
173
- if (typeof plugin?.onInit === 'function') {
174
- befly.appContext[plugin.pluginName] = await plugin?.onInit(befly.appContext);
175
- } else {
176
- befly.appContext[plugin.pluginName] = {};
177
- }
178
- }
179
35
 
180
- /**
181
- * 加载所有插件
182
- * @param befly - Befly实例(需要访问 pluginLists 和 appContext)
183
- */
184
- export async function loadPlugins(befly: { pluginLists: Plugin[]; appContext: BeflyContext }): Promise<void> {
185
- try {
186
- const loadStartTime = Bun.nanoseconds();
187
- const loadedPluginNames = new Set<string>();
36
+ // 3. 扫描项目插件
37
+ const appPlugins = await scanModules<Plugin>(projectPluginDir, 'app', '插件', befly.pluginsConfig);
188
38
 
189
- // 阶段1:扫描所有插件
190
- const corePlugins = await scanCorePlugins(loadedPluginNames);
191
- const addonPlugins = await scanAddonPlugins(loadedPluginNames);
192
- const userPlugins = await scanUserPlugins(loadedPluginNames);
39
+ // 4. 合并所有插件
40
+ allPlugins.push(...corePlugins);
41
+ allPlugins.push(...addonPlugins);
42
+ allPlugins.push(...appPlugins);
193
43
 
194
- // 阶段2:分层排序插件
195
- const sortedCorePlugins = sortPlugins(corePlugins);
196
- if (sortedCorePlugins === false) {
197
- Logger.error('核心插件依赖关系错误,请检查插件的 after 属性');
198
- process.exit(1);
199
- }
44
+ // 5. 过滤禁用的插件
45
+ const disablePlugins = (befly as any).config?.disablePlugins || [];
46
+ const enabledPlugins = allPlugins.filter((plugin) => !disablePlugins.includes(plugin.name));
200
47
 
201
- const sortedAddonPlugins = sortPlugins(addonPlugins);
202
- if (sortedAddonPlugins === false) {
203
- Logger.error('组件插件依赖关系错误,请检查插件的 after 属性');
204
- process.exit(1);
48
+ if (disablePlugins.length > 0) {
49
+ Logger.info(`禁用插件: ${disablePlugins.join(', ')}`);
205
50
  }
206
51
 
207
- const sortedUserPlugins = sortPlugins(userPlugins);
208
- if (sortedUserPlugins === false) {
209
- Logger.error('用户插件依赖关系错误,请检查插件的 after 属性');
52
+ // 6. 排序与初始化
53
+ const sortedPlugins = sortModules(enabledPlugins);
54
+ if (sortedPlugins === false) {
55
+ Logger.error('插件依赖关系错误,请检查 after 属性');
210
56
  process.exit(1);
211
57
  }
212
58
 
213
- // 阶段3:分层初始化插件(核心 组件 用户)
214
- // 3.1 初始化核心插件
215
- for (const plugin of sortedCorePlugins) {
59
+ for (const plugin of sortedPlugins) {
216
60
  try {
217
- await initPlugin(befly, plugin);
218
- } catch (error: any) {
219
- Logger.error(`核心插件 ${plugin.pluginName} 初始化失败`, error);
220
- process.exit(1);
221
- }
222
- }
61
+ befly.pluginLists.push(plugin);
223
62
 
224
- // 3.2 初始化组件插件
225
- for (const plugin of sortedAddonPlugins) {
226
- try {
227
- await initPlugin(befly, plugin);
63
+ if (typeof plugin.handler === 'function') {
64
+ befly.appContext[plugin.name!] = await plugin.handler(befly.appContext);
65
+ } else {
66
+ befly.appContext[plugin.name!] = {};
67
+ }
228
68
  } catch (error: any) {
229
- Logger.error(`组件插件 ${plugin.pluginName} 初始化失败`, error);
69
+ Logger.error(`插件 ${plugin.name} 初始化失败`, error);
230
70
  process.exit(1);
231
71
  }
232
72
  }
233
-
234
- // 3.3 初始化用户插件
235
- for (const plugin of sortedUserPlugins) {
236
- try {
237
- await initPlugin(befly, plugin);
238
- } catch (error: any) {
239
- Logger.error(`用户插件 ${plugin.pluginName} 初始化失败`, error);
240
- process.exit(1);
241
- }
242
- }
243
-
244
- const totalLoadTime = calcPerfTime(loadStartTime);
245
73
  } catch (error: any) {
246
74
  Logger.error('加载插件时发生错误', error);
247
75
  process.exit(1);
248
76
  }
249
77
  }
78
+
79
+ // ==================== 钩子加载逻辑 ====================
80
+ // 已移动到 loadHooks.ts
package/main.ts CHANGED
@@ -3,39 +3,34 @@
3
3
  * 提供简洁的框架接口,核心逻辑已提取到 loader 层
4
4
  */
5
5
 
6
- import { Env } from './env.js';
6
+ // ========== 外部依赖 ==========
7
+ import { calcPerfTime } from 'befly-util';
7
8
 
9
+ // ========== 相对导入 ==========
8
10
  import { Logger } from './lib/logger.js';
9
11
  import { Cipher } from './lib/cipher.js';
10
12
  import { Jwt } from './lib/jwt.js';
11
13
  import { Database } from './lib/database.js';
14
+ import { DbHelper } from './lib/dbHelper.js';
15
+ import { RedisHelper } from './lib/redisHelper.js';
12
16
  import { loadPlugins } from './loader/loadPlugins.js';
17
+ import { loadHooks } from './loader/loadHooks.js';
13
18
  import { loadApis } from './loader/loadApis.js';
14
19
  import { rootHandler } from './router/root.js';
15
20
  import { apiHandler } from './router/api.js';
16
21
  import { staticHandler } from './router/static.js';
22
+ import { checkApp } from './checks/checkApp.js';
23
+ import { checkTable } from './checks/checkTable.js';
24
+ import { checkApi } from './checks/checkApi.js';
25
+ import { syncAllCommand } from './sync/syncAll.js';
17
26
  import { coreDir } from './paths.js';
18
- import { DbHelper } from './lib/dbHelper.js';
19
- import { RedisHelper } from './lib/redisHelper.js';
20
- import { checkTable, checkApi, checkApp } from './check.js';
21
- import {
22
- //
23
- Yes,
24
- No,
25
- keysToSnake,
26
- keysToCamel,
27
- arrayKeysToCamel,
28
- pickFields,
29
- fieldClear,
30
- calcPerfTime,
31
- scanAddons,
32
- getAddonDir,
33
- addonDirExists
34
- } from './util.js';
27
+ import { defaultOptions } from './config.js';
35
28
 
29
+ // ========== 类型导入 ==========
36
30
  import type { Server } from 'bun';
37
- import type { BeflyContext } from './types/befly.js';
31
+ import type { BeflyContext, BeflyOptions } from './types/befly.js';
38
32
  import type { Plugin } from './types/plugin.js';
33
+ import type { Hook } from './types/hook.js';
39
34
  import type { ApiRoute } from './types/api.js';
40
35
  /**
41
36
  * Befly 框架核心类
@@ -48,142 +43,120 @@ export class Befly {
48
43
  /** 插件列表 */
49
44
  private pluginLists: Plugin[] = [];
50
45
 
46
+ /** 钩子列表 */
47
+ private hookLists: Hook[] = [];
48
+
51
49
  /** 应用上下文 */
52
50
  public appContext: BeflyContext;
53
51
 
54
- constructor() {
52
+ /** 最终配置(合并默认值后) */
53
+ public config: BeflyOptions;
54
+
55
+ constructor(options: BeflyOptions = {}) {
55
56
  this.appContext = {};
57
+ // 合并配置:用户配置 > 默认配置(最多 2 级)
58
+ this.config = { ...defaultOptions };
59
+ for (const key in options) {
60
+ const value = options[key as keyof BeflyOptions];
61
+ if (value !== undefined && value !== null) {
62
+ if (typeof value === 'object' && !Array.isArray(value)) {
63
+ this.config[key as keyof BeflyOptions] = { ...defaultOptions[key as keyof typeof defaultOptions], ...value } as any;
64
+ } else {
65
+ this.config[key as keyof BeflyOptions] = value as any;
66
+ }
67
+ }
68
+ }
56
69
  }
57
70
 
58
71
  /**
59
72
  * 启动完整的生命周期流程
60
73
  * @returns HTTP 服务器实例
61
74
  */
62
- private async start(): Promise<Server> {
63
- const serverStartTime = Bun.nanoseconds();
64
-
65
- // 1. 加载所有 API(动态导入必须在最前面,避免 Bun 1.3.2 的崩溃 bug)
66
- await loadApis(this.apiRoutes);
67
-
68
- // 2. 执行项目结构检查
69
- const appCheckResult = await checkApp();
70
- if (!appCheckResult) {
71
- Logger.error('项目结构检查失败,程序退出');
75
+ public async start(): Promise<Server> {
76
+ try {
77
+ const serverStartTime = Bun.nanoseconds();
78
+
79
+ // 1. 执行启动检查
80
+ await checkApp();
81
+ await checkTable();
82
+ await checkApi();
83
+
84
+ // 4. 加载插件
85
+ await loadPlugins({
86
+ pluginLists: this.pluginLists,
87
+ appContext: this.appContext,
88
+ pluginsConfig: this.config as any
89
+ });
90
+
91
+ // 5. 加载钩子
92
+ await loadHooks({
93
+ hookLists: this.hookLists,
94
+ pluginsConfig: this.config as any
95
+ });
96
+
97
+ // 6. 加载所有 API
98
+ await loadApis(this.apiRoutes);
99
+
100
+ // 7. 自动同步 (默认开启)
101
+ await syncAllCommand(this.config);
102
+
103
+ // 8. 启动 HTTP 服务器
104
+ const server = Bun.serve({
105
+ port: this.config.appPort,
106
+ hostname: this.config.appHost,
107
+ routes: {
108
+ '/': rootHandler,
109
+ '/api/*': apiHandler(this.apiRoutes, this.hookLists, this.appContext),
110
+ '/*': staticHandler(this.config.cors)
111
+ },
112
+ error: (error: Error) => {
113
+ Logger.error('服务启动时发生错误', error);
114
+ return Response.json({ code: 1, msg: '内部服务器错误' });
115
+ }
116
+ });
117
+
118
+ const finalStartupTime = calcPerfTime(serverStartTime);
119
+ Logger.info(`${this.config.appName} 启动成功! `);
120
+ Logger.info(`服务器启动耗时: ${finalStartupTime}`);
121
+ Logger.info(`服务器监听地址: http://${this.config.appHost}:${this.config.appPort}`);
122
+
123
+ // 9. 注册优雅关闭处理
124
+ const gracefulShutdown = async (signal: string) => {
125
+ // 停止接收新请求
126
+ server.stop(true);
127
+ Logger.info('HTTP 服务器已停止');
128
+
129
+ // 关闭数据库连接
130
+ try {
131
+ await Database.disconnect();
132
+ Logger.info('数据库连接已关闭');
133
+ } catch (error: any) {
134
+ Logger.error('关闭数据库连接时出错:', error);
135
+ }
136
+
137
+ Logger.info('服务器已优雅关闭');
138
+ process.exit(0);
139
+ };
140
+
141
+ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
142
+ process.on('SIGINT', () => gracefulShutdown('SIGINT'));
143
+
144
+ return server;
145
+ } catch (error: any) {
146
+ Logger.error('Befly 启动失败', error);
72
147
  process.exit(1);
73
148
  }
74
-
75
- // 3. 执行表定义检查
76
- const tableCheckResult = await checkTable();
77
- if (!tableCheckResult) {
78
- Logger.error('表定义检查失败,程序退出');
79
- process.exit(1);
80
- }
81
-
82
- // 4. 执行 API 定义检查
83
- const apiCheckResult = await checkApi();
84
- if (!apiCheckResult) {
85
- Logger.error('API 定义检查失败,程序退出');
86
- process.exit(1);
87
- }
88
-
89
- // 5. 加载插件
90
- await loadPlugins({
91
- pluginLists: this.pluginLists,
92
- appContext: this.appContext
93
- });
94
-
95
- // 4. 启动 HTTP 服务器
96
- const totalStartupTime = calcPerfTime(serverStartTime);
97
-
98
- return await this.startServer();
99
- }
100
-
101
- /**
102
- * 启动 HTTP 服务器
103
- * @returns HTTP 服务器实例
104
- */
105
- private async startServer(): Promise<Server> {
106
- const startTime = Bun.nanoseconds();
107
-
108
- const server = Bun.serve({
109
- port: Env.APP_PORT,
110
- hostname: Env.APP_HOST,
111
- routes: {
112
- '/': rootHandler,
113
- '/api/*': apiHandler(this.apiRoutes, this.pluginLists, this.appContext),
114
- '/*': staticHandler
115
- },
116
- error: (error: Error) => {
117
- Logger.error('服务启动时发生错误', error);
118
- return Response.json({ code: 1, msg: '内部服务器错误' });
119
- }
120
- });
121
-
122
- const finalStartupTime = calcPerfTime(startTime);
123
- Logger.info(`${Env.APP_NAME} 启动成功! `);
124
- Logger.info(`服务器启动耗时: ${finalStartupTime}`);
125
- Logger.info(`服务器监听地址: http://${Env.APP_HOST}:${Env.APP_PORT}`);
126
-
127
- return server;
128
- }
129
-
130
- /**
131
- * 启动服务器并注册优雅关闭处理
132
- */
133
- async listen(): Promise<Server> {
134
- const server = await this.start();
135
-
136
- const gracefulShutdown = async (signal: string) => {
137
- // 1. 停止接收新请求
138
- server.stop(true);
139
- Logger.info('HTTP 服务器已停止');
140
-
141
- // 2. 关闭数据库连接
142
- try {
143
- await Database.disconnect();
144
- Logger.info('数据库连接已关闭');
145
- } catch (error: any) {
146
- Logger.err('关闭数据库连接时出错:', error);
147
- }
148
-
149
- Logger.info('服务器已优雅关闭');
150
- process.exit(0);
151
- };
152
-
153
- process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
154
- process.on('SIGINT', () => gracefulShutdown('SIGINT'));
155
-
156
- return server;
157
149
  }
158
150
  }
159
151
 
160
152
  // 核心类和工具导出
161
153
  export {
162
154
  // 配置
163
- Env,
164
155
  Logger,
165
156
  Cipher,
166
157
  Jwt,
167
- Yes,
168
- No,
169
158
  Database,
170
159
  DbHelper,
171
160
  RedisHelper,
172
- coreDir,
173
- checkTable,
174
- checkApi,
175
- checkApp
176
- };
177
-
178
- // 工具函数命名空间导出
179
- export const utils = {
180
- keysToSnake: keysToSnake,
181
- keysToCamel: keysToCamel,
182
- arrayKeysToCamel: arrayKeysToCamel,
183
- pickFields: pickFields,
184
- fieldClear: fieldClear,
185
- calcPerfTime: calcPerfTime,
186
- scanAddons: scanAddons,
187
- getAddonDir: getAddonDir,
188
- addonDirExists: addonDirExists
161
+ coreDir
189
162
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.8.18",
3
+ "version": "3.8.20",
4
4
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -9,14 +9,15 @@
9
9
  "registry": "https://registry.npmjs.org"
10
10
  },
11
11
  "main": "main.ts",
12
- "types": "./types/index.d.ts",
12
+ "types": "main.ts",
13
13
  "exports": {
14
14
  ".": {
15
+ "types": "./main.ts",
15
16
  "default": "./main.ts"
16
17
  },
17
18
  "./types": {
18
- "types": "./types/index.d.ts",
19
- "default": "./types/index.d.ts"
19
+ "types": "./types/index.ts",
20
+ "default": "./types/index.ts"
20
21
  }
21
22
  },
22
23
  "scripts": {
@@ -38,6 +39,8 @@
38
39
  "homepage": "https://chensuiyi.me",
39
40
  "license": "Apache-2.0",
40
41
  "files": [
42
+ "sync/",
43
+ "config/",
41
44
  "lib/",
42
45
  "loader/",
43
46
  "plugins/",
@@ -51,9 +54,9 @@
51
54
  "LICENSE",
52
55
  "main.ts",
53
56
  "check.ts",
54
- "env.ts",
55
57
  "paths.ts",
56
- "util.ts",
58
+ "response.ts",
59
+ "dist/",
57
60
  "package.json",
58
61
  "README.md",
59
62
  "LICENSE"
@@ -62,8 +65,13 @@
62
65
  "bun": ">=1.3.0"
63
66
  },
64
67
  "dependencies": {
68
+ "befly-util": "0.1.2",
69
+ "chalk": "^5.6.2",
65
70
  "es-toolkit": "^1.41.0",
66
71
  "pathe": "^2.0.3"
67
72
  },
68
- "gitHead": "29e1bc79619581b841052206a59b124e027dfd20"
73
+ "gitHead": "e43aefa3abeda7a35669778793d39b23b4180c4e",
74
+ "devDependencies": {
75
+ "typescript": "^5.9.3"
76
+ }
69
77
  }
package/paths.ts CHANGED
@@ -39,6 +39,16 @@ export const coreCheckDir = join(__dirname, 'checks');
39
39
  */
40
40
  export const corePluginDir = join(__dirname, 'plugins');
41
41
 
42
+ /**
43
+ * Core 框架钩子目录
44
+ * @description packages/core/hooks/
45
+ * @usage 存放内置钩子(auth, cors, parser 等)
46
+ */
47
+ export const coreHookDir = join(__dirname, 'hooks');
48
+
49
+ /**
50
+ * Core 框架 API 目录
51
+
42
52
  /**
43
53
  * Core 框架 API 目录
44
54
  * @description packages/core/apis/
@@ -76,6 +86,16 @@ export const projectCheckDir = join(projectDir, 'checks');
76
86
  */
77
87
  export const projectPluginDir = join(projectDir, 'plugins');
78
88
 
89
+ /**
90
+ * 项目钩子目录
91
+ * @description {projectDir}/hooks/
92
+ * @usage 存放用户自定义钩子
93
+ */
94
+ export const projectHookDir = join(projectDir, 'hooks');
95
+
96
+ /**
97
+ * 项目 API 目录
98
+
79
99
  /**
80
100
  * 项目 API 目录
81
101
  * @description {projectDir}/apis/