befly 2.3.2 → 3.0.0

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 (93) hide show
  1. package/apis/health/info.ts +64 -0
  2. package/apis/tool/tokenCheck.ts +51 -0
  3. package/bin/befly.ts +202 -0
  4. package/checks/conflict.ts +408 -0
  5. package/checks/table.ts +284 -0
  6. package/config/env.ts +218 -0
  7. package/config/reserved.ts +96 -0
  8. package/main.ts +101 -0
  9. package/package.json +45 -16
  10. package/plugins/{db.js → db.ts} +25 -12
  11. package/plugins/logger.ts +28 -0
  12. package/plugins/redis.ts +51 -0
  13. package/plugins/tool.ts +34 -0
  14. package/scripts/syncDb/apply.ts +171 -0
  15. package/scripts/syncDb/constants.ts +70 -0
  16. package/scripts/syncDb/ddl.ts +182 -0
  17. package/scripts/syncDb/helpers.ts +172 -0
  18. package/scripts/syncDb/index.ts +215 -0
  19. package/scripts/syncDb/schema.ts +199 -0
  20. package/scripts/syncDb/sqlite.ts +50 -0
  21. package/scripts/syncDb/state.ts +104 -0
  22. package/scripts/syncDb/table.ts +204 -0
  23. package/scripts/syncDb/tableCreate.ts +142 -0
  24. package/scripts/syncDb/tests/constants.test.ts +104 -0
  25. package/scripts/syncDb/tests/ddl.test.ts +134 -0
  26. package/scripts/syncDb/tests/helpers.test.ts +70 -0
  27. package/scripts/syncDb/types.ts +92 -0
  28. package/scripts/syncDb/version.ts +73 -0
  29. package/scripts/syncDb.ts +9 -0
  30. package/scripts/syncDev.ts +112 -0
  31. package/system.ts +149 -0
  32. package/tables/_common.json +21 -0
  33. package/tables/admin.json +10 -0
  34. package/tsconfig.json +58 -0
  35. package/types/api.d.ts +246 -0
  36. package/types/befly.d.ts +234 -0
  37. package/types/common.d.ts +215 -0
  38. package/types/context.ts +167 -0
  39. package/types/crypto.d.ts +23 -0
  40. package/types/database.d.ts +278 -0
  41. package/types/index.d.ts +16 -0
  42. package/types/index.ts +459 -0
  43. package/types/jwt.d.ts +99 -0
  44. package/types/logger.d.ts +43 -0
  45. package/types/plugin.d.ts +109 -0
  46. package/types/redis.d.ts +44 -0
  47. package/types/tool.d.ts +67 -0
  48. package/types/validator.d.ts +45 -0
  49. package/utils/addonHelper.ts +60 -0
  50. package/utils/api.ts +23 -0
  51. package/utils/{colors.js → colors.ts} +79 -21
  52. package/utils/crypto.ts +308 -0
  53. package/utils/datetime.ts +51 -0
  54. package/utils/dbHelper.ts +142 -0
  55. package/utils/errorHandler.ts +68 -0
  56. package/utils/index.ts +46 -0
  57. package/utils/jwt.ts +493 -0
  58. package/utils/logger.ts +284 -0
  59. package/utils/objectHelper.ts +68 -0
  60. package/utils/pluginHelper.ts +62 -0
  61. package/utils/redisHelper.ts +338 -0
  62. package/utils/response.ts +38 -0
  63. package/utils/{sqlBuilder.js → sqlBuilder.ts} +233 -97
  64. package/utils/sqlHelper.ts +447 -0
  65. package/utils/tableHelper.ts +167 -0
  66. package/utils/tool.ts +230 -0
  67. package/utils/typeHelper.ts +101 -0
  68. package/utils/validate.ts +451 -0
  69. package/utils/{xml.js → xml.ts} +100 -74
  70. package/.npmrc +0 -3
  71. package/.prettierignore +0 -2
  72. package/.prettierrc +0 -11
  73. package/apis/health/info.js +0 -49
  74. package/apis/tool/tokenCheck.js +0 -29
  75. package/checks/table.js +0 -221
  76. package/config/env.js +0 -62
  77. package/main.js +0 -579
  78. package/plugins/logger.js +0 -14
  79. package/plugins/redis.js +0 -32
  80. package/plugins/tool.js +0 -8
  81. package/scripts/syncDb.js +0 -603
  82. package/system.js +0 -118
  83. package/tables/common.json +0 -16
  84. package/tables/tool.json +0 -6
  85. package/utils/api.js +0 -27
  86. package/utils/crypto.js +0 -260
  87. package/utils/index.js +0 -387
  88. package/utils/jwt.js +0 -387
  89. package/utils/logger.js +0 -143
  90. package/utils/redisHelper.js +0 -74
  91. package/utils/sqlManager.js +0 -471
  92. package/utils/tool.js +0 -31
  93. package/utils/validate.js +0 -228
package/config/env.ts ADDED
@@ -0,0 +1,218 @@
1
+ /**
2
+ * 环境变量配置 - TypeScript 版本
3
+ * 类型化所有环境变量
4
+ */
5
+
6
+ /**
7
+ * 环境变量配置接口
8
+ */
9
+ export interface EnvConfig {
10
+ // ========== 项目配置 ==========
11
+ /** 项目模式:development | production | test */
12
+ NODE_ENV: string;
13
+ /** 应用名称 */
14
+ APP_NAME: string;
15
+ /** MD5 加密盐 */
16
+ MD5_SALT: string;
17
+ /** 监听端口 */
18
+ APP_PORT: number;
19
+ /** 监听主机 */
20
+ APP_HOST: string;
21
+ /** 超级管理员密码 */
22
+ DEV_PASSWORD: string;
23
+ /** 请求体大小限制(字节) */
24
+ BODY_LIMIT: number;
25
+ /** 是否进行参数验证 */
26
+ PARAMS_CHECK: string;
27
+
28
+ // ========== 日志配置 ==========
29
+ /** 日志等级:debug | info | warn | error */
30
+ LOG_LEVEL: string;
31
+ /** 日志排除字段(逗号分隔) */
32
+ LOG_EXCLUDE_FIELDS: string;
33
+ /** 日志目录 */
34
+ LOG_DIR: string;
35
+ /** 是否输出到控制台:0 | 1 */
36
+ LOG_TO_CONSOLE: number;
37
+ /** 日志文件最大大小(字节) */
38
+ LOG_MAX_SIZE: number;
39
+
40
+ // ========== 时区配置 ==========
41
+ /** 时区:Asia/Shanghai */
42
+ TZ: string;
43
+
44
+ // ========== 数据库配置 ==========
45
+ /** 是否启用数据库:0 | 1 */
46
+ DB_ENABLE: number;
47
+ /** 数据库类型:sqlite | mysql | postgresql */
48
+ DB_TYPE: string;
49
+ /** 数据库主机 */
50
+ DB_HOST: string;
51
+ /** 数据库端口 */
52
+ DB_PORT: number;
53
+ /** 数据库用户名 */
54
+ DB_USER: string;
55
+ /** 数据库密码 */
56
+ DB_PASS: string;
57
+ /** 数据库名称 */
58
+ DB_NAME: string;
59
+ /** 是否启用调试:0 | 1 */
60
+ DB_DEBUG: number;
61
+ /** 连接池最大连接数 */
62
+ DB_POOL_MAX: number;
63
+
64
+ // ========== Redis 配置 ==========
65
+ /** 是否启用 Redis:0 | 1 */
66
+ REDIS_ENABLE: number;
67
+ /** Redis 主机 */
68
+ REDIS_HOST: string;
69
+ /** Redis 端口 */
70
+ REDIS_PORT: number;
71
+ /** Redis 用户名 */
72
+ REDIS_USERNAME: string;
73
+ /** Redis 密码 */
74
+ REDIS_PASSWORD: string;
75
+ /** Redis 数据库索引 */
76
+ REDIS_DB: number;
77
+ /** Redis 键前缀 */
78
+ REDIS_KEY_PREFIX: string;
79
+
80
+ // ========== JWT 配置 ==========
81
+ /** JWT 密钥 */
82
+ JWT_SECRET: string;
83
+ /** JWT 过期时间:7d | 30d | 1h */
84
+ JWT_EXPIRES_IN: string;
85
+ /** JWT 算法:HS256 | HS384 | HS512 */
86
+ JWT_ALGORITHM: string;
87
+
88
+ // ========== CORS 配置 ==========
89
+ /** 允许的来源 */
90
+ ALLOWED_ORIGIN: string;
91
+ /** 允许的方法 */
92
+ ALLOWED_METHODS: string;
93
+ /** 允许的头部 */
94
+ ALLOWED_HEADERS: string;
95
+ /** 暴露的头部 */
96
+ EXPOSE_HEADERS: string;
97
+ /** 预检请求缓存时间(秒) */
98
+ MAX_AGE: number;
99
+ /** 是否允许凭证 */
100
+ ALLOW_CREDENTIALS: string;
101
+
102
+ // ========== 邮件配置 ==========
103
+ /** 邮件服务器主机 */
104
+ MAIL_HOST: string;
105
+ /** 邮件服务器端口 */
106
+ MAIL_PORT: number;
107
+ /** 是否使用连接池 */
108
+ MAIL_POOL: string;
109
+ /** 是否使用 SSL */
110
+ MAIL_SECURE: string;
111
+ /** 邮件用户名 */
112
+ MAIL_USER: string;
113
+ /** 邮件密码 */
114
+ MAIL_PASS: string;
115
+ /** 发件人名称 */
116
+ MAIL_SENDER: string;
117
+ /** 发件人地址 */
118
+ MAIL_ADDRESS: string;
119
+
120
+ // ========== 同步脚本配置 ==========
121
+ /** 是否合并 ALTER 语句 */
122
+ SYNC_MERGE_ALTER: string;
123
+ /** 是否同步在线索引 */
124
+ SYNC_ONLINE_INDEX: string;
125
+ /** 是否禁止字段缩小 */
126
+ SYNC_DISALLOW_SHRINK: string;
127
+ /** 是否允许类型变更 */
128
+ SYNC_ALLOW_TYPE_CHANGE: string;
129
+ }
130
+
131
+ /**
132
+ * 获取环境变量值(带默认值)
133
+ */
134
+ const getEnv = (key: string, defaultValue: string = ''): string => {
135
+ return process.env[key] || defaultValue;
136
+ };
137
+
138
+ /**
139
+ * 获取数字类型环境变量
140
+ */
141
+ const getEnvNumber = (key: string, defaultValue: number = 0): number => {
142
+ const value = process.env[key];
143
+ return value ? Number(value) : defaultValue;
144
+ };
145
+
146
+ /**
147
+ * 环境变量配置对象
148
+ */
149
+ export const Env: EnvConfig = {
150
+ // ========== 项目配置 ==========
151
+ NODE_ENV: getEnv('NODE_ENV', 'development'),
152
+ APP_NAME: getEnv('APP_NAME', 'befly'),
153
+ MD5_SALT: getEnv('MD5_SALT', 'befly'),
154
+ APP_PORT: getEnvNumber('APP_PORT', 3000),
155
+ APP_HOST: getEnv('APP_HOST', '0.0.0.0'),
156
+ DEV_PASSWORD: getEnv('DEV_PASSWORD', ''),
157
+ BODY_LIMIT: getEnvNumber('BODY_LIMIT', 10485760), // 10MB
158
+ PARAMS_CHECK: getEnv('PARAMS_CHECK', 'true'),
159
+
160
+ // ========== 日志配置 ==========
161
+ LOG_LEVEL: getEnv('LOG_LEVEL', 'info'),
162
+ LOG_EXCLUDE_FIELDS: getEnv('LOG_EXCLUDE_FIELDS', 'password,token,secret'),
163
+ LOG_DIR: getEnv('LOG_DIR', './logs'),
164
+ LOG_TO_CONSOLE: getEnvNumber('LOG_TO_CONSOLE', 1),
165
+ LOG_MAX_SIZE: getEnvNumber('LOG_MAX_SIZE', 10485760), // 10MB
166
+
167
+ // ========== 时区配置 ==========
168
+ TZ: getEnv('TZ', 'Asia/Shanghai'),
169
+
170
+ // ========== 数据库配置 ==========
171
+ DB_ENABLE: getEnvNumber('DB_ENABLE', 1),
172
+ DB_TYPE: getEnv('DB_TYPE', 'mysql'),
173
+ DB_HOST: getEnv('DB_HOST', 'localhost'),
174
+ DB_PORT: getEnvNumber('DB_PORT', 3306),
175
+ DB_USER: getEnv('DB_USER', 'root'),
176
+ DB_PASS: getEnv('DB_PASS', ''),
177
+ DB_NAME: getEnv('DB_NAME', 'befly'),
178
+ DB_DEBUG: getEnvNumber('DB_DEBUG', 0),
179
+ DB_POOL_MAX: getEnvNumber('DB_POOL_MAX', 10),
180
+
181
+ // ========== Redis 配置 ==========
182
+ REDIS_ENABLE: getEnvNumber('REDIS_ENABLE', 1),
183
+ REDIS_HOST: getEnv('REDIS_HOST', 'localhost'),
184
+ REDIS_PORT: getEnvNumber('REDIS_PORT', 6379),
185
+ REDIS_USERNAME: getEnv('REDIS_USERNAME', ''),
186
+ REDIS_PASSWORD: getEnv('REDIS_PASSWORD', ''),
187
+ REDIS_DB: getEnvNumber('REDIS_DB', 0),
188
+ REDIS_KEY_PREFIX: getEnv('REDIS_KEY_PREFIX', 'befly'),
189
+
190
+ // ========== JWT 配置 ==========
191
+ JWT_SECRET: getEnv('JWT_SECRET', 'befly-secret'),
192
+ JWT_EXPIRES_IN: getEnv('JWT_EXPIRES_IN', '7d'),
193
+ JWT_ALGORITHM: getEnv('JWT_ALGORITHM', 'HS256'),
194
+
195
+ // ========== CORS 配置 ==========
196
+ ALLOWED_ORIGIN: getEnv('ALLOWED_ORIGIN', '*'),
197
+ ALLOWED_METHODS: getEnv('ALLOWED_METHODS', 'GET, POST, PUT, DELETE, OPTIONS'),
198
+ ALLOWED_HEADERS: getEnv('ALLOWED_HEADERS', 'Content-Type, Authorization, authorization, token'),
199
+ EXPOSE_HEADERS: getEnv('EXPOSE_HEADERS', 'Content-Range, X-Content-Range, Authorization, authorization, token'),
200
+ MAX_AGE: getEnvNumber('MAX_AGE', 86400),
201
+ ALLOW_CREDENTIALS: getEnv('ALLOW_CREDENTIALS', 'true'),
202
+
203
+ // ========== 邮件配置 ==========
204
+ MAIL_HOST: getEnv('MAIL_HOST', ''),
205
+ MAIL_PORT: getEnvNumber('MAIL_PORT', 587),
206
+ MAIL_POOL: getEnv('MAIL_POOL', 'true'),
207
+ MAIL_SECURE: getEnv('MAIL_SECURE', 'false'),
208
+ MAIL_USER: getEnv('MAIL_USER', ''),
209
+ MAIL_PASS: getEnv('MAIL_PASS', ''),
210
+ MAIL_SENDER: getEnv('MAIL_SENDER', ''),
211
+ MAIL_ADDRESS: getEnv('MAIL_ADDRESS', ''),
212
+
213
+ // ========== 同步脚本配置 ==========
214
+ SYNC_MERGE_ALTER: getEnv('SYNC_MERGE_ALTER', 'false'),
215
+ SYNC_ONLINE_INDEX: getEnv('SYNC_ONLINE_INDEX', 'false'),
216
+ SYNC_DISALLOW_SHRINK: getEnv('SYNC_DISALLOW_SHRINK', 'true'),
217
+ SYNC_ALLOW_TYPE_CHANGE: getEnv('SYNC_ALLOW_TYPE_CHANGE', 'false')
218
+ };
@@ -0,0 +1,96 @@
1
+ /**
2
+ * 核心保留名称配置
3
+ * 定义框架保留的资源名称,防止用户和 addon 使用
4
+ */
5
+
6
+ /**
7
+ * 保留名称配置
8
+ */
9
+ export const RESERVED_NAMES = {
10
+ /**
11
+ * 核心表前缀(禁止用户使用)
12
+ */
13
+ tablePrefix: ['sys_'],
14
+
15
+ /**
16
+ * 核心 API 路由前缀(禁止用户使用)
17
+ */
18
+ apiRoutes: ['/api/health', '/api/tool'],
19
+
20
+ /**
21
+ * 核心插件名(禁止用户使用)
22
+ */
23
+ plugins: ['db', 'logger', 'redis', 'tool'],
24
+
25
+ /**
26
+ * 禁止用作 addon 名称
27
+ */
28
+ addonNames: ['core', 'system', 'admin', 'sys', 'befly', 'app', 'api', 'config', 'utils', 'types']
29
+ } as const;
30
+
31
+ /**
32
+ * 检测表名是否使用了保留前缀
33
+ */
34
+ export function isReservedTableName(tableName: string): boolean {
35
+ return RESERVED_NAMES.tablePrefix.some((prefix) => tableName.startsWith(prefix));
36
+ }
37
+
38
+ /**
39
+ * 检测 API 路由是否使用了保留路径
40
+ */
41
+ export function isReservedRoute(route: string): boolean {
42
+ // 移除方法前缀(如 POST/GET)
43
+ const path = route.replace(/^(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)\//i, '/');
44
+ return RESERVED_NAMES.apiRoutes.some((reserved) => path.startsWith(reserved));
45
+ }
46
+
47
+ /**
48
+ * 检测插件名是否使用了保留名称
49
+ */
50
+ export function isReservedPluginName(pluginName: string): boolean {
51
+ // 检测核心插件名
52
+ if (RESERVED_NAMES.plugins.includes(pluginName)) {
53
+ return true;
54
+ }
55
+ // 检测是否使用点号命名空间但前缀是保留名称
56
+ if (pluginName.includes('.')) {
57
+ const prefix = pluginName.split('.')[0];
58
+ return RESERVED_NAMES.plugins.includes(prefix);
59
+ }
60
+ return false;
61
+ }
62
+
63
+ /**
64
+ * 检测 addon 名称是否使用了保留名称
65
+ */
66
+ export function isReservedAddonName(addonName: string): boolean {
67
+ return RESERVED_NAMES.addonNames.includes(addonName.toLowerCase());
68
+ }
69
+
70
+ /**
71
+ * 获取保留前缀列表(用于错误提示)
72
+ */
73
+ export function getReservedTablePrefixes(): string[] {
74
+ return [...RESERVED_NAMES.tablePrefix];
75
+ }
76
+
77
+ /**
78
+ * 获取保留路由列表(用于错误提示)
79
+ */
80
+ export function getReservedRoutes(): string[] {
81
+ return [...RESERVED_NAMES.apiRoutes];
82
+ }
83
+
84
+ /**
85
+ * 获取保留插件名列表(用于错误提示)
86
+ */
87
+ export function getReservedPlugins(): string[] {
88
+ return [...RESERVED_NAMES.plugins];
89
+ }
90
+
91
+ /**
92
+ * 获取保留 addon 名称列表(用于错误提示)
93
+ */
94
+ export function getReservedAddonNames(): string[] {
95
+ return [...RESERVED_NAMES.addonNames];
96
+ }
package/main.ts ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Befly 框架主入口文件 - TypeScript 版本
3
+ * 提供完整的框架功能:检查系统、加载插件、加载 API、启动 HTTP 服务器
4
+ */
5
+
6
+ import { Env } from './config/env.js';
7
+ import { Api } from './utils/api.js';
8
+ import { Yes, No } from './utils/index.js';
9
+ import { Logger } from './utils/logger.js';
10
+ import { Jwt } from './utils/jwt.js';
11
+ import { Validator } from './utils/validate.js';
12
+ import { Crypto2 } from './utils/crypto.js';
13
+ import { calcPerfTime } from './utils/index.js';
14
+ import { scanAddons, hasAddonDir } from './utils/addonHelper.js';
15
+ import { Checker } from './lifecycle/checker.js';
16
+ import { Loader } from './lifecycle/loader.js';
17
+ import { Bootstrap } from './lifecycle/bootstrap.js';
18
+
19
+ import type { Server } from 'bun';
20
+ import type { Plugin } from './types/plugin.js';
21
+ import type { ApiRoute, ApiHandler } from './types/api.js';
22
+ import type { BeflyContext, BeflyOptions, RequestContext } from './types/befly.js';
23
+
24
+ /**
25
+ * Befly 框架核心类
26
+ */
27
+ export class Befly {
28
+ /** API 路由映射表 */
29
+ private apiRoutes: Map<string, ApiRoute>;
30
+
31
+ /** 插件列表 */
32
+ private pluginLists: Plugin[];
33
+
34
+ /** 应用上下文 */
35
+ public appContext: BeflyContext;
36
+
37
+ /** 应用配置选项 */
38
+ private appOptions: BeflyOptions;
39
+
40
+ // 原构造函数被替换
41
+ constructor(options: BeflyOptions = {}) {
42
+ this.apiRoutes = new Map();
43
+ this.pluginLists = [];
44
+ this.appContext = {};
45
+ this.appOptions = options;
46
+ }
47
+
48
+ /**
49
+ * 系统检查(已提取到 lifecycle/checker.ts)
50
+ */
51
+ async initCheck(): Promise<void> {
52
+ await Checker.run();
53
+ }
54
+
55
+ /**
56
+ * 加载插件(已提取到 lifecycle/loader.ts)
57
+ */
58
+ async loadPlugins(): Promise<void> {
59
+ await Loader.loadPlugins(this);
60
+ }
61
+
62
+ /**
63
+ * 加载API路由(已提取到 lifecycle/loader.ts)
64
+ */
65
+ async loadApis(dirName: string, options?: { isAddon?: boolean; addonName?: string }): Promise<void> {
66
+ await Loader.loadApis(dirName, this.apiRoutes, options);
67
+ }
68
+
69
+ /**
70
+ * 启动服务器
71
+ */
72
+ async listen(callback?: (server: Server) => void): Promise<void> {
73
+ const serverStartTime = Bun.nanoseconds();
74
+ Logger.info('开始启动 Befly 服务器...');
75
+
76
+ // 执行启动前的检查和加载
77
+ await this.initCheck();
78
+ await this.loadPlugins();
79
+ await this.loadApis('core');
80
+
81
+ // 加载 addon APIs
82
+ const addons = scanAddons();
83
+ for (const addon of addons) {
84
+ if (hasAddonDir(addon, 'apis')) {
85
+ await this.loadApis(addon, { isAddon: true, addonName: addon });
86
+ }
87
+ }
88
+
89
+ await this.loadApis('app');
90
+
91
+ const totalStartupTime = calcPerfTime(serverStartTime);
92
+ Logger.info(`服务器启动准备完成,总耗时: ${totalStartupTime}`);
93
+
94
+ // 启动HTTP服务器(路由处理逻辑已提取到 router/*.ts)
95
+ await Bootstrap.start(this, callback);
96
+ }
97
+ }
98
+
99
+ // 核心类已通过 export class 导出
100
+ export { Env, Api, Jwt, Validator, Crypto2, Logger, Yes, No };
101
+ export type { ApiOptions, FieldRules } from './types/api.js';
package/package.json CHANGED
@@ -1,42 +1,69 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "2.3.2",
4
- "description": "Buma - 为 Bun 专属打造的 API 接口框架核心引擎",
3
+ "version": "3.0.0",
4
+ "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
7
7
  "publishConfig": {
8
8
  "access": "public",
9
9
  "registry": "https://registry.npmjs.org"
10
10
  },
11
- "main": "main.js",
11
+ "main": "main.ts",
12
+ "types": "main.ts",
12
13
  "exports": {
13
- ".": "./main.js"
14
+ ".": {
15
+ "types": "./main.ts",
16
+ "default": "./main.ts"
17
+ },
18
+ "./types": {
19
+ "types": "./types/index.ts",
20
+ "default": "./types/index.ts"
21
+ },
22
+ "./types/*": {
23
+ "types": "./types/*.ts",
24
+ "default": "./types/*.ts"
25
+ },
26
+ "./utils": {
27
+ "types": "./utils/index.ts",
28
+ "default": "./utils/index.ts"
29
+ },
30
+ "./utils/*": {
31
+ "types": "./utils/*.ts",
32
+ "default": "./utils/*.ts"
33
+ },
34
+ "./config": {
35
+ "types": "./config/env.ts",
36
+ "default": "./config/env.ts"
37
+ }
14
38
  },
15
- "scripts": {
16
- "ra": "bun run ../release.js --major",
17
- "rb": "bun run ../release.js --minor",
18
- "rc": "bun run ../release.js --patch"
39
+ "bin": {
40
+ "befly": "./bin/befly.ts"
19
41
  },
42
+ "scripts": {},
20
43
  "keywords": [
21
44
  "bun",
22
45
  "api",
23
46
  "framework",
24
47
  "core",
48
+ "typescript",
25
49
  "javascript",
26
50
  "backend",
27
51
  "rest",
28
- "http"
52
+ "http",
53
+ "type-safe"
29
54
  ],
30
55
  "author": "chensuiyi <bimostyle@qq.com>",
31
56
  "homepage": "https://chensuiyi.me",
32
57
  "license": "Apache-2.0",
33
58
  "files": [
59
+ "bin/",
34
60
  "apis/",
35
61
  "checks/",
36
62
  "config/",
37
63
  "plugins/",
38
64
  "scripts/",
39
65
  "tables/",
66
+ "types/",
40
67
  "utils/",
41
68
  ".gitignore",
42
69
  ".npmignore",
@@ -46,17 +73,19 @@
46
73
  ".prettierignore",
47
74
  ".prettierrc",
48
75
  "bunfig.toml",
76
+ "tsconfig.json",
49
77
  "LICENSE",
78
+ "main.ts",
50
79
  "main.js",
80
+ "system.ts",
51
81
  "system.js",
52
82
  "package.json",
53
83
  "README.md"
54
84
  ],
55
- "simple-git-hooks": {
56
- "pre-commit": "bunx --bun lint-staged"
85
+ "engines": {
86
+ "bun": ">=1.3.0"
57
87
  },
58
- "lint-staged": {
59
- "*.{js,css,scss,less,ts,jsx,vue,html,json,md,yaml}": "bunx --bun prettier --write --cache --ignore-unknown"
60
- },
61
- "gitHead": "1dc5f118a723969456559e758e2ba889f4601224"
62
- }
88
+ "devDependencies": {
89
+ "@types/bun": "latest"
90
+ }
91
+ }
@@ -1,29 +1,40 @@
1
+ /**
2
+ * 数据库插件 - TypeScript 版本
3
+ * 初始化数据库连接和 SQL 管理器
4
+ */
5
+
1
6
  import { Env } from '../config/env.js';
2
7
  import { Logger } from '../utils/logger.js';
3
8
  import { createSqlClient } from '../utils/index.js';
4
- import { SqlManager } from '../utils/sqlManager.js';
5
-
6
- // 统一使用 utils/index.js 提供的 createSqlClient
9
+ import { SqlHelper } from '../utils/sqlHelper.js';
10
+ import type { Plugin } from '../types/plugin.js';
11
+ import type { BeflyContext } from '../types/befly.js';
7
12
 
8
- export default {
13
+ /**
14
+ * 数据库插件
15
+ */
16
+ const dbPlugin: Plugin = {
17
+ name: '_db',
9
18
  after: ['_redis'],
10
- async onInit(befly) {
11
- let sql = null;
19
+
20
+ async onInit(befly: BeflyContext): Promise<SqlHelper | Record<string, never>> {
21
+ let sql: any = null;
12
22
 
13
23
  try {
14
- if (Env.MYSQL_ENABLE === 1) {
24
+ if (Env.DB_ENABLE === 1) {
15
25
  // 创建 Bun SQL 客户端(内置连接池),并确保连接验证成功后再继续
16
26
  sql = await createSqlClient();
17
27
 
18
- // 创建数据库管理器实例(迁移到 utils/sqlManager.js)
19
- const dbManager = new SqlManager(sql, befly);
28
+ // 创建数据库管理器实例,直接传入 sql 对象
29
+ const dbManager = new SqlHelper(befly, sql);
20
30
 
31
+ Logger.info('数据库插件初始化成功');
21
32
  return dbManager;
22
33
  } else {
23
- Logger.warn(`MySQL 未启用,跳过初始化`);
34
+ Logger.warn('数据库未启用(DB_ENABLE≠1),跳过初始化');
24
35
  return {};
25
36
  }
26
- } catch (error) {
37
+ } catch (error: any) {
27
38
  Logger.error({
28
39
  msg: '数据库初始化失败',
29
40
  message: error.message,
@@ -34,7 +45,7 @@ export default {
34
45
  if (sql) {
35
46
  try {
36
47
  await sql.close();
37
- } catch (cleanupError) {
48
+ } catch (cleanupError: any) {
38
49
  Logger.error('清理连接池失败:', cleanupError);
39
50
  }
40
51
  }
@@ -44,3 +55,5 @@ export default {
44
55
  }
45
56
  }
46
57
  };
58
+
59
+ export default dbPlugin;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * 日志插件 - TypeScript 版本
3
+ * 提供全局日志功能
4
+ */
5
+
6
+ import { Logger } from '../utils/logger.js';
7
+ import type { Plugin } from '../types/plugin.js';
8
+ import type { BeflyContext } from '../types/befly.js';
9
+
10
+ /**
11
+ * 日志插件
12
+ */
13
+ const loggerPlugin: Plugin = {
14
+ name: '_logger',
15
+ after: [],
16
+
17
+ async onInit(befly: BeflyContext): Promise<typeof Logger> {
18
+ try {
19
+ Logger.info('日志插件初始化成功');
20
+ return Logger;
21
+ } catch (error: any) {
22
+ // 插件内禁止直接退出进程,抛出异常交由主流程统一处理
23
+ throw error;
24
+ }
25
+ }
26
+ };
27
+
28
+ export default loggerPlugin;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Redis 插件 - TypeScript 版本
3
+ * 初始化 Redis 连接和助手工具
4
+ */
5
+
6
+ import { Env } from '../config/env.js';
7
+ import { Logger } from '../utils/logger.js';
8
+ import { RedisHelper, initRedisClient, getRedisClient } from '../utils/redisHelper.js';
9
+ import type { Plugin } from '../types/plugin.js';
10
+ import type { BeflyContext } from '../types/befly.js';
11
+
12
+ /**
13
+ * Redis 插件
14
+ */
15
+ const redisPlugin: Plugin = {
16
+ name: '_redis',
17
+ after: ['_logger'],
18
+
19
+ async onInit(befly: BeflyContext): Promise<typeof RedisHelper | Record<string, never>> {
20
+ try {
21
+ if (Env.REDIS_ENABLE === 1) {
22
+ // 初始化 Redis 客户端(带连接测试)
23
+ await initRedisClient();
24
+
25
+ Logger.info('Redis 插件初始化成功', {
26
+ host: Env.REDIS_HOST,
27
+ port: Env.REDIS_PORT,
28
+ db: Env.REDIS_DB
29
+ });
30
+
31
+ // 返回工具对象,向下游以相同 API 暴露
32
+ return RedisHelper;
33
+ } else {
34
+ Logger.warn('Redis 未启用,跳过初始化');
35
+ return {};
36
+ }
37
+ } catch (error: any) {
38
+ Logger.error({
39
+ msg: 'Redis 初始化失败',
40
+ message: error.message,
41
+ code: error.code,
42
+ stack: error.stack
43
+ });
44
+
45
+ // 插件内禁止直接退出进程,抛出异常交由主流程统一处理
46
+ throw error;
47
+ }
48
+ }
49
+ };
50
+
51
+ export default redisPlugin;