befly 3.4.15 → 3.5.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.
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
@@ -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
 
@@ -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) {
@@ -175,11 +166,7 @@ export async function syncCommand(options: SyncOptions) {
175
166
  // ========== Addon 命令 ==========
176
167
  export const addonCommand = {
177
168
  async install(name: string, options: { source?: string }) {
178
- const spinner = ora({
179
- text: `正在安装插件: ${name}`,
180
- color: 'cyan',
181
- spinner: 'dots'
182
- }).start();
169
+ Logger.info(`正在安装插件: ${name}`);
183
170
 
184
171
  try {
185
172
  // TODO: 实现插件安装逻辑
@@ -188,19 +175,15 @@ export const addonCommand = {
188
175
  // 3. 安装插件依赖
189
176
  // 4. 执行插件安装脚本
190
177
 
191
- spinner.succeed(`插件 ${name} 安装成功`);
178
+ Logger.success(`插件 ${name} 安装成功`);
192
179
  } catch (error) {
193
- spinner.fail(`插件 ${name} 安装失败`);
180
+ Logger.error(`插件 ${name} 安装失败`);
194
181
  throw error;
195
182
  }
196
183
  },
197
184
 
198
185
  async uninstall(name: string, options: { keepData: boolean }) {
199
- const spinner = ora({
200
- text: `正在卸载插件: ${name}`,
201
- color: 'cyan',
202
- spinner: 'dots'
203
- }).start();
186
+ Logger.info(`正在卸载插件: ${name}`);
204
187
 
205
188
  try {
206
189
  // TODO: 实现插件卸载逻辑
@@ -208,9 +191,9 @@ export const addonCommand = {
208
191
  // 2. 删除插件文件
209
192
  // 3. 可选:删除插件数据
210
193
 
211
- spinner.succeed(`插件 ${name} 卸载成功`);
194
+ Logger.success(`插件 ${name} 卸载成功`);
212
195
  } catch (error) {
213
- spinner.fail(`插件 ${name} 卸载失败`);
196
+ Logger.error(`插件 ${name} 卸载失败`);
214
197
  throw error;
215
198
  }
216
199
  },
@@ -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
 
package/config/env.ts CHANGED
@@ -87,17 +87,17 @@ export interface EnvConfig {
87
87
 
88
88
  // ========== CORS 配置 ==========
89
89
  /** 允许的来源 */
90
- ALLOWED_ORIGIN: string;
90
+ CORS_ALLOWED_ORIGIN: string;
91
91
  /** 允许的方法 */
92
- ALLOWED_METHODS: string;
92
+ CORS_ALLOWED_METHODS: string;
93
93
  /** 允许的头部 */
94
- ALLOWED_HEADERS: string;
94
+ CORS_ALLOWED_HEADERS: string;
95
95
  /** 暴露的头部 */
96
- EXPOSE_HEADERS: string;
96
+ CORS_EXPOSE_HEADERS: string;
97
97
  /** 预检请求缓存时间(秒) */
98
- MAX_AGE: number;
98
+ CORS_MAX_AGE: number;
99
99
  /** 是否允许凭证 */
100
- ALLOW_CREDENTIALS: string;
100
+ CORS_ALLOW_CREDENTIALS: string;
101
101
 
102
102
  // ========== 邮件配置 ==========
103
103
  /** 邮件服务器主机 */
@@ -183,12 +183,12 @@ export const Env: EnvConfig = {
183
183
  JWT_ALGORITHM: getEnv('JWT_ALGORITHM', 'HS256'),
184
184
 
185
185
  // ========== CORS 配置 ==========
186
- ALLOWED_ORIGIN: getEnv('ALLOWED_ORIGIN', '*'),
187
- ALLOWED_METHODS: getEnv('ALLOWED_METHODS', 'GET, POST, PUT, DELETE, OPTIONS'),
188
- ALLOWED_HEADERS: getEnv('ALLOWED_HEADERS', 'Content-Type, Authorization, authorization, token'),
189
- EXPOSE_HEADERS: getEnv('EXPOSE_HEADERS', 'Content-Range, X-Content-Range, Authorization, authorization, token'),
190
- MAX_AGE: getEnvNumber('MAX_AGE', 86400),
191
- ALLOW_CREDENTIALS: getEnv('ALLOW_CREDENTIALS', 'true'),
186
+ CORS_ALLOWED_ORIGIN: getEnv('CORS_ALLOWED_ORIGIN', '*'),
187
+ CORS_ALLOWED_METHODS: getEnv('CORS_ALLOWED_METHODS', 'GET, POST, PUT, DELETE, OPTIONS'),
188
+ CORS_ALLOWED_HEADERS: getEnv('CORS_ALLOWED_HEADERS', 'Content-Type, Authorization, authorization, token'),
189
+ CORS_EXPOSE_HEADERS: getEnv('CORS_EXPOSE_HEADERS', 'Content-Range, X-Content-Range, Authorization, authorization, token'),
190
+ CORS_MAX_AGE: getEnvNumber('CORS_MAX_AGE', 86400),
191
+ CORS_ALLOW_CREDENTIALS: getEnv('CORS_ALLOW_CREDENTIALS', 'true'),
192
192
 
193
193
  // ========== 邮件配置 ==========
194
194
  MAIL_HOST: getEnv('MAIL_HOST', ''),
package/lib/middleware.ts CHANGED
@@ -58,42 +58,14 @@ 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
- // 如果配置了 ALLOWED_ORIGIN
65
- if (Env.ALLOWED_ORIGIN) {
66
- // 如果配置为 *,使用请求的 origin(而不是返回 *)
67
- if (Env.ALLOWED_ORIGIN === '*') {
68
- allowedOrigin = requestOrigin || '*';
69
- } else {
70
- // 支持多个源,用逗号分隔
71
- const allowedOrigins = Env.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
- // 没有配置 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.ALLOWED_METHODS || 'GET, POST, PUT, DELETE, OPTIONS',
93
- 'Access-Control-Allow-Headers': Env.ALLOWED_HEADERS || 'Content-Type, Authorization, authorization, token',
94
- 'Access-Control-Expose-Headers': Env.EXPOSE_HEADERS || 'Content-Range, X-Content-Range, Authorization, authorization, token',
95
- 'Access-Control-Max-Age': Env.MAX_AGE || 86400,
96
- 'Access-Control-Allow-Credentials': Env.ALLOW_CREDENTIALS || 'true'
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,
67
+ 'Access-Control-Max-Age': Env.CORS_MAX_AGE || 86400,
68
+ 'Access-Control-Allow-Credentials': Env.CORS_ALLOW_CREDENTIALS || 'true'
97
69
  }
98
70
  };
99
71
  };
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';
@@ -34,6 +35,7 @@ export class Befly {
34
35
  */
35
36
  async listen(callback?: (server: Server) => void): Promise<Server> {
36
37
  const server = await this.lifecycle.start(this.appContext, callback);
38
+ Logger.info('数据库======:' + Env.APP_NAME);
37
39
 
38
40
  // 注册优雅关闭信号处理器
39
41
  const gracefulShutdown = async (signal: string) => {
@@ -45,7 +47,6 @@ export class Befly {
45
47
 
46
48
  // 2. 关闭数据库连接
47
49
  try {
48
- const { Database } = await import('./lib/database.js');
49
50
  await Database.disconnect();
50
51
  Logger.info('✅ 数据库连接已关闭');
51
52
  } catch (error: any) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.4.15",
3
+ "version": "3.5.0",
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": "f7fad19e6c07b776a4a3c1aa83d09497ababb719"
83
+ "gitHead": "6d065b50bd57e1330a81d5a62423b204a2a49205"
85
84
  }
package/router/api.ts CHANGED
@@ -117,37 +117,7 @@ export function apiHandler(apiRoutes: Map<string, ApiRoute>, pluginLists: Plugin
117
117
  // 记录详细的错误日志
118
118
  Logger.warn(api ? `接口 [${api.name}] 执行失败` : '处理接口请求时发生错误', error);
119
119
 
120
- // 根据错误类型返回不同的错误信息
121
- let errorMessage = '内部服务器错误';
122
- let errorDetail = {};
123
-
124
- // 数据库错误
125
- if (error.message?.includes('ECONNREFUSED') || error.message?.includes('database')) {
126
- errorMessage = '数据库连接失败';
127
- }
128
- // Redis错误
129
- else if (error.message?.includes('Redis') || error.message?.includes('redis')) {
130
- errorMessage = 'Redis服务异常';
131
- }
132
- // 权限错误
133
- else if (error.message?.includes('permission') || error.message?.includes('权限')) {
134
- errorMessage = '权限不足';
135
- }
136
- // 认证错误
137
- else if (error.message?.includes('token') || error.message?.includes('认证')) {
138
- errorMessage = '认证失败';
139
- }
140
-
141
- // 开发环境返回详细错误信息
142
- if (Env.NODE_ENV === 'development') {
143
- errorDetail = {
144
- type: error.constructor?.name || 'Error',
145
- message: error.message,
146
- stack: error.stack
147
- };
148
- }
149
-
150
- return Response.json(No(errorMessage, errorDetail), {
120
+ return Response.json(No('内部服务器错误'), {
151
121
  headers: corsOptions.headers
152
122
  });
153
123
  }