befly 3.5.6 → 3.6.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 (83) hide show
  1. package/lib/addon.ts +77 -0
  2. package/lib/database.ts +2 -2
  3. package/lib/logger.ts +6 -15
  4. package/lifecycle/checker.ts +20 -49
  5. package/lifecycle/lifecycle.ts +7 -5
  6. package/lifecycle/loader.ts +5 -5
  7. package/main.ts +10 -1
  8. package/package.json +2 -9
  9. package/paths.ts +5 -54
  10. package/plugins/db.ts +1 -1
  11. package/types/database.d.ts +1 -1
  12. package/util.ts +1 -83
  13. package/apis/admin/del.ts +0 -35
  14. package/apis/admin/info.ts +0 -50
  15. package/apis/admin/ins.ts +0 -61
  16. package/apis/admin/list.ts +0 -20
  17. package/apis/admin/roleDetail.ts +0 -35
  18. package/apis/admin/roleSave.ts +0 -40
  19. package/apis/admin/upd.ts +0 -51
  20. package/apis/api/all.ts +0 -37
  21. package/apis/auth/login.ts +0 -78
  22. package/apis/auth/logout.ts +0 -23
  23. package/apis/auth/register.ts +0 -50
  24. package/apis/auth/sendSmsCode.ts +0 -36
  25. package/apis/cache/refresh.ts +0 -34
  26. package/apis/dashboard/addonList.ts +0 -47
  27. package/apis/dashboard/changelog.ts +0 -37
  28. package/apis/dashboard/configStatus.ts +0 -54
  29. package/apis/dashboard/environmentInfo.ts +0 -46
  30. package/apis/dashboard/performanceMetrics.ts +0 -23
  31. package/apis/dashboard/permissionStats.ts +0 -31
  32. package/apis/dashboard/serviceStatus.ts +0 -82
  33. package/apis/dashboard/systemInfo.ts +0 -26
  34. package/apis/dashboard/systemOverview.ts +0 -32
  35. package/apis/dashboard/systemResources.ts +0 -119
  36. package/apis/dict/all.ts +0 -25
  37. package/apis/dict/del.ts +0 -19
  38. package/apis/dict/detail.ts +0 -21
  39. package/apis/dict/ins.ts +0 -27
  40. package/apis/dict/list.ts +0 -18
  41. package/apis/dict/upd.ts +0 -31
  42. package/apis/menu/all.ts +0 -68
  43. package/apis/menu/del.ts +0 -37
  44. package/apis/menu/ins.ts +0 -20
  45. package/apis/menu/list.ts +0 -21
  46. package/apis/menu/upd.ts +0 -29
  47. package/apis/role/apiDetail.ts +0 -30
  48. package/apis/role/apiSave.ts +0 -41
  49. package/apis/role/del.ts +0 -44
  50. package/apis/role/detail.ts +0 -24
  51. package/apis/role/ins.ts +0 -39
  52. package/apis/role/list.ts +0 -14
  53. package/apis/role/menuDetail.ts +0 -30
  54. package/apis/role/menuSave.ts +0 -38
  55. package/apis/role/save.ts +0 -44
  56. package/apis/role/upd.ts +0 -40
  57. package/bin/index.ts +0 -34
  58. package/checks/conflict.ts +0 -351
  59. package/checks/table.ts +0 -250
  60. package/commands/index.ts +0 -73
  61. package/commands/sync.ts +0 -88
  62. package/commands/syncApi.ts +0 -316
  63. package/commands/syncDb/apply.ts +0 -171
  64. package/commands/syncDb/constants.ts +0 -77
  65. package/commands/syncDb/ddl.ts +0 -191
  66. package/commands/syncDb/helpers.ts +0 -173
  67. package/commands/syncDb/index.ts +0 -217
  68. package/commands/syncDb/schema.ts +0 -199
  69. package/commands/syncDb/sqlite.ts +0 -50
  70. package/commands/syncDb/state.ts +0 -112
  71. package/commands/syncDb/table.ts +0 -214
  72. package/commands/syncDb/tableCreate.ts +0 -149
  73. package/commands/syncDb/types.ts +0 -92
  74. package/commands/syncDb/version.ts +0 -73
  75. package/commands/syncDb.ts +0 -34
  76. package/commands/syncDev.ts +0 -237
  77. package/commands/syncMenu.ts +0 -349
  78. package/commands/util.ts +0 -58
  79. package/tables/admin.json +0 -14
  80. package/tables/api.json +0 -8
  81. package/tables/dict.json +0 -8
  82. package/tables/menu.json +0 -8
  83. package/tables/role.json +0 -8
package/lib/addon.ts ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Addon 管理工具类
3
+ * 提供 addon 的扫描、路径获取等功能
4
+ */
5
+
6
+ import fs from 'node:fs';
7
+ import { join } from 'pathe';
8
+ import { existsSync, statSync, readdirSync } from 'node:fs';
9
+ import { projectDir } from '../paths.js';
10
+
11
+ /**
12
+ * Addon 管理类
13
+ */
14
+ export class Addon {
15
+ /**
16
+ * 扫描所有可用的 addon
17
+ * @returns addon 名称数组
18
+ */
19
+ static scan(): string[] {
20
+ const beflyDir = join(projectDir, 'node_modules', '@befly-addon');
21
+
22
+ if (!existsSync(beflyDir)) {
23
+ return [];
24
+ }
25
+
26
+ try {
27
+ return fs
28
+ .readdirSync(beflyDir)
29
+ .filter((name) => {
30
+ // addon 名称格式:admin, demo 等(不带 addon- 前缀)
31
+ const fullPath = join(beflyDir, name);
32
+ try {
33
+ const stat = statSync(fullPath);
34
+ return stat.isDirectory();
35
+ } catch {
36
+ return false;
37
+ }
38
+ })
39
+ .sort();
40
+ } catch {
41
+ return [];
42
+ }
43
+ }
44
+
45
+ /**
46
+ * 获取 addon 的指定子目录路径
47
+ * @param name - addon 名称
48
+ * @param subDir - 子目录名称
49
+ * @returns 完整路径
50
+ */
51
+ static getDir(name: string, subDir: string): string {
52
+ return join(projectDir, 'node_modules', '@befly-addon', name, subDir);
53
+ }
54
+
55
+ /**
56
+ * 检查 addon 子目录是否存在
57
+ * @param name - addon 名称
58
+ * @param subDir - 子目录名称
59
+ * @returns 是否存在
60
+ */
61
+ static dirExists(name: string, subDir: string): boolean {
62
+ const dir = this.getDir(name, subDir);
63
+ return existsSync(dir) && statSync(dir).isDirectory();
64
+ }
65
+
66
+ /**
67
+ * 获取插件目录列表
68
+ * @param addonsDir - addons 根目录路径
69
+ * @returns 插件名称数组
70
+ */
71
+ static getDirs(addonsDir: string): string[] {
72
+ return readdirSync(addonsDir).filter((name) => {
73
+ const addonPath = join(addonsDir, name);
74
+ return statSync(addonPath).isDirectory() && !name.startsWith('_');
75
+ });
76
+ }
77
+ }
package/lib/database.ts CHANGED
@@ -62,7 +62,7 @@ export class Database {
62
62
  }
63
63
 
64
64
  try {
65
- const timeout = options.connectionTimeout ?? 5000;
65
+ const timeout = options.connectionTimeout ?? 30000;
66
66
 
67
67
  const healthCheckPromise = (async () => {
68
68
  let version = '';
@@ -174,7 +174,7 @@ export class Database {
174
174
  const url = `redis://${auth}${REDIS_HOST}:${REDIS_PORT}/${REDIS_DB}`;
175
175
 
176
176
  const redis = new RedisClient(url, {
177
- connectionTimeout: 10000,
177
+ connectionTimeout: 30000,
178
178
  idleTimeout: 0,
179
179
  autoReconnect: true,
180
180
  maxRetries: 0,
package/lib/logger.ts CHANGED
@@ -5,7 +5,6 @@
5
5
 
6
6
  import { join } from 'pathe';
7
7
  import { appendFile, stat } from 'node:fs/promises';
8
- import chalk from 'chalk';
9
8
  import { Env } from '../env.js';
10
9
  import type { LogLevel } from '../types/common.js';
11
10
 
@@ -54,12 +53,6 @@ export class Logger {
54
53
 
55
54
  // 格式化消息
56
55
  const timestamp = formatDate();
57
- const colorMap = {
58
- info: chalk.greenBright,
59
- debug: chalk.cyanBright,
60
- warn: chalk.yellowBright,
61
- error: chalk.redBright
62
- };
63
56
 
64
57
  // 处理消息内容
65
58
  let content = '';
@@ -69,19 +62,17 @@ export class Logger {
69
62
  content = String(message);
70
63
  }
71
64
 
72
- // 带颜色的控制台消息
73
- const coloredLevelStr = colorMap[level](level.toUpperCase().padStart(5));
74
- const coloredMessage = `[${timestamp}] ${coloredLevelStr} - ${content}`;
65
+ // 格式化日志消息
66
+ const levelStr = level.toUpperCase().padStart(5);
67
+ const logMessage = `[${timestamp}] ${levelStr} - ${content}`;
75
68
 
76
69
  // 控制台输出
77
70
  if (this.config.toConsole) {
78
- console.log(coloredMessage);
71
+ console.log(logMessage);
79
72
  }
80
73
 
81
- // 文件输出(去除 ANSI 颜色代码)
82
- const plainLevelStr = level.toUpperCase().padStart(5);
83
- const plainMessage = `[${timestamp}] ${plainLevelStr} - ${content}`;
84
- await this.writeToFile(plainMessage, level);
74
+ // 文件输出
75
+ await this.writeToFile(logMessage, level);
85
76
  }
86
77
 
87
78
  /**
@@ -6,8 +6,9 @@
6
6
  import { join, basename } from 'pathe';
7
7
  import { Logger } from '../lib/logger.js';
8
8
  import { calcPerfTime } from '../util.js';
9
- import { coreCheckDir } from '../paths.js';
10
- import { scanAddons, getAddonDir, addonDirExists } from '../util.js';
9
+ import { projectCheckDir } from '../paths.js';
10
+ import { checkDefault } from '../check.js';
11
+ import { Addon } from '../lib/addon.js';
11
12
 
12
13
  /**
13
14
  * 系统检查器类
@@ -20,6 +21,9 @@ export class Checker {
20
21
  try {
21
22
  const checkStartTime = Bun.nanoseconds();
22
23
 
24
+ // 先执行默认检查(有异常会自动抛出)
25
+ await checkDefault();
26
+
23
27
  const glob = new Bun.Glob('*.{ts}');
24
28
 
25
29
  // 统计信息
@@ -29,50 +33,19 @@ export class Checker {
29
33
  failedChecks: 0
30
34
  };
31
35
 
32
- // 1. 优先执行资源冲突检测(如果存在)
33
- try {
34
- const conflictCheckPath = join(coreCheckDir, 'conflict.ts');
35
- const conflictCheckFile = Bun.file(conflictCheckPath);
36
-
37
- if (await conflictCheckFile.exists()) {
38
- stats.totalChecks++;
39
- const conflictCheckStart = Bun.nanoseconds();
36
+ // 检查目录列表:先项目,后 addons
37
+ const checkDirs: Array<{ path: string; type: 'app' | 'addon'; addonName?: string }> = [];
40
38
 
41
- const conflictModule = await import(conflictCheckPath);
42
- const conflictCheckFn = conflictModule.default;
39
+ // 添加项目 checks 目录
40
+ checkDirs.push({ path: projectCheckDir, type: 'app' });
43
41
 
44
- if (typeof conflictCheckFn === 'function') {
45
- const conflictResult = await conflictCheckFn();
46
- const conflictCheckTime = calcPerfTime(conflictCheckStart);
47
-
48
- if (typeof conflictResult !== 'boolean') {
49
- Logger.warn(`核心检查 conflict.ts 返回值必须为 true 或 false,当前为 ${typeof conflictResult}`);
50
- stats.failedChecks++;
51
- } else if (conflictResult === true) {
52
- stats.passedChecks++;
53
- } else {
54
- Logger.warn(`核心检查未通过: conflict.ts`);
55
- stats.failedChecks++;
56
- // 资源冲突检测失败,立即终止
57
- Logger.warn('资源冲突检测失败,无法继续启动');
58
- process.exit(1);
59
- }
60
- }
61
- }
62
- } catch (error: any) {
63
- Logger.error('执行资源冲突检测时出错:', error);
64
- stats.failedChecks++;
65
- }
66
-
67
- // 2. 检查目录列表:先核心,后项目,最后 addons
68
- // 检查所有 checks 目录
69
- const checkDirs = [{ path: coreCheckDir, type: 'core' as const }]; // 添加所有 addon 的 checks 目录
70
- const addons = scanAddons();
42
+ // 添加所有 addon checks 目录
43
+ const addons = Addon.scan();
71
44
  for (const addon of addons) {
72
- if (addonDirExists(addon, 'checks')) {
45
+ if (Addon.dirExists(addon, 'checks')) {
73
46
  checkDirs.push({
74
- path: getAddonDir(addon, 'checks'),
75
- type: 'addon' as const,
47
+ path: Addon.getDir(addon, 'checks'),
48
+ type: 'addon',
76
49
  addonName: addon
77
50
  });
78
51
  }
@@ -80,9 +53,10 @@ export class Checker {
80
53
 
81
54
  // 按顺序扫描并执行检查函数
82
55
  for (const checkConfig of checkDirs) {
83
- const { path: checkDir, type } = checkConfig;
56
+ const { path: checkDir, type: type } = checkConfig;
84
57
  const addonName = 'addonName' in checkConfig ? checkConfig.addonName : undefined;
85
- const checkTypeLabel = type === 'core' ? '核心' : type === 'project' ? '项目' : `组件${addonName}`;
58
+ const checkTypeLabel = type === 'app' ? '项目' : `组件${addonName}`;
59
+
86
60
  for await (const file of glob.scan({
87
61
  cwd: checkDir,
88
62
  onlyFiles: true,
@@ -91,9 +65,6 @@ export class Checker {
91
65
  const fileName = basename(file);
92
66
  if (fileName.startsWith('_')) continue; // 跳过以下划线开头的文件
93
67
 
94
- // 跳过已经执行过的 conflict.ts
95
- if (type === 'core' && fileName === 'conflict.ts') continue;
96
-
97
68
  try {
98
69
  stats.totalChecks++;
99
70
  const singleCheckStart = Bun.nanoseconds();
@@ -135,10 +106,10 @@ export class Checker {
135
106
 
136
107
  // 输出检查结果统计
137
108
  if (stats.failedChecks > 0) {
138
- Logger.error(`✗ 系统检查失败: ${stats.failedChecks}/${stats.totalChecks},耗时: ${totalCheckTime}`);
109
+ Logger.error(`系统检查失败: ${stats.failedChecks}/${stats.totalChecks},耗时: ${totalCheckTime}`);
139
110
  process.exit(1);
140
111
  } else if (stats.totalChecks > 0) {
141
- Logger.info(`✓ 系统检查通过: ${stats.passedChecks}/${stats.totalChecks},耗时: ${totalCheckTime}`);
112
+ Logger.info(`系统检查通过: ${stats.passedChecks}/${stats.totalChecks},耗时: ${totalCheckTime}`);
142
113
  }
143
114
  } catch (error: any) {
144
115
  Logger.error('执行系统检查时发生错误', error);
@@ -4,10 +4,12 @@
4
4
  */
5
5
 
6
6
  import { Logger } from '../lib/logger.js';
7
- import { calcPerfTime } from '../util.js';
8
- import { scanAddons, addonDirExists } from '../util.js';
9
- import { Checker } from './checker.js';
7
+ import { Database } from '../lib/database.js';
10
8
  import { Loader } from './loader.js';
9
+ import { Checker } from './checker.js';
10
+ import { Env } from '../env.js';
11
+ import { calcPerfTime } from '../util.js';
12
+ import { Addon } from '../lib/addon.js';
11
13
  import { Bootstrap } from './bootstrap.js';
12
14
 
13
15
  import type { Server } from 'bun';
@@ -78,10 +80,10 @@ export class Lifecycle {
78
80
  }
79
81
 
80
82
  // 2. 加载 addon APIs
81
- const addons = scanAddons();
83
+ const addons = Addon.scan();
82
84
 
83
85
  for (const addon of addons) {
84
- const hasApis = addonDirExists(addon, 'apis');
86
+ const hasApis = Addon.dirExists(addon, 'apis');
85
87
  if (hasApis) {
86
88
  try {
87
89
  await Loader.loadApis(addon, this.apiRoutes, { where: 'addon', addonName: addon });
@@ -9,7 +9,7 @@ import { isPlainObject } from 'es-toolkit/compat';
9
9
  import { Logger } from '../lib/logger.js';
10
10
  import { calcPerfTime } from '../util.js';
11
11
  import { corePluginDir, projectPluginDir, coreApiDir, projectApiDir } from '../paths.js';
12
- import { scanAddons, getAddonDir, addonDirExists } from '../util.js';
12
+ import { Addon } from '../lib/addon.js';
13
13
  import type { Plugin } from '../types/plugin.js';
14
14
  import type { ApiRoute } from '../types/api.js';
15
15
  import type { BeflyContext } from '../types/befly.js';
@@ -148,13 +148,13 @@ export class Loader {
148
148
  Logger.info(`✓ 核心插件加载完成: ${corePlugins.length} 个,耗时: ${corePluginsScanTime}`);
149
149
 
150
150
  // 扫描 addon 插件目录
151
- const addons = scanAddons();
151
+ const addons = Addon.scan();
152
152
  if (addons.length > 0) {
153
153
  const addonPluginsScanStart = Bun.nanoseconds();
154
154
  for (const addon of addons) {
155
- if (!addonDirExists(addon, 'plugins')) continue;
155
+ if (!Addon.dirExists(addon, 'plugins')) continue;
156
156
 
157
- const addonPluginsDir = getAddonDir(addon, 'plugins');
157
+ const addonPluginsDir = Addon.getDir(addon, 'plugins');
158
158
  for await (const file of glob.scan({
159
159
  cwd: addonPluginsDir,
160
160
  onlyFiles: true,
@@ -325,7 +325,7 @@ export class Loader {
325
325
  if (where === 'core') {
326
326
  apiDir = coreApiDir;
327
327
  } else if (where === 'addon') {
328
- apiDir = getAddonDir(addonName, 'apis');
328
+ apiDir = Addon.getDir(addonName, 'apis');
329
329
  } else {
330
330
  apiDir = projectApiDir;
331
331
  }
package/main.ts CHANGED
@@ -10,6 +10,10 @@ import { Cipher } from './lib/cipher.js';
10
10
  import { Jwt } from './lib/jwt.js';
11
11
  import { Database } from './lib/database.js';
12
12
  import { Lifecycle } from './lifecycle/lifecycle.js';
13
+ import { coreDir } from './paths.js';
14
+ import { DbHelper } from './lib/dbHelper.js';
15
+ import { RedisHelper } from './lib/redisHelper.js';
16
+ import { Addon } from './lib/addon.js';
13
17
 
14
18
  import type { Server } from 'bun';
15
19
  import type { BeflyContext, BeflyOptions } from './types/befly.js';
@@ -71,5 +75,10 @@ export {
71
75
  Cipher,
72
76
  Jwt,
73
77
  Yes,
74
- No
78
+ No,
79
+ coreDir,
80
+ Database,
81
+ DbHelper,
82
+ RedisHelper,
83
+ Addon
75
84
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly",
3
- "version": "3.5.6",
3
+ "version": "3.6.0",
4
4
  "description": "Befly - 为 Bun 专属打造的 TypeScript API 接口框架核心引擎",
5
5
  "type": "module",
6
6
  "private": false,
@@ -10,9 +10,6 @@
10
10
  },
11
11
  "main": "main.ts",
12
12
  "types": "./types/index.d.ts",
13
- "bin": {
14
- "befly": "./bin/index.ts"
15
- },
16
13
  "exports": {
17
14
  ".": {
18
15
  "default": "./main.ts"
@@ -30,7 +27,6 @@
30
27
  "api",
31
28
  "framework",
32
29
  "core",
33
- "cli",
34
30
  "typescript",
35
31
  "javascript",
36
32
  "backend",
@@ -42,10 +38,8 @@
42
38
  "homepage": "https://chensuiyi.me",
43
39
  "license": "Apache-2.0",
44
40
  "files": [
45
- "bin/",
46
41
  "apis/",
47
42
  "checks/",
48
- "commands/",
49
43
  "config/",
50
44
  "lib/",
51
45
  "lifecycle/",
@@ -76,9 +70,8 @@
76
70
  "bun": ">=1.3.0"
77
71
  },
78
72
  "dependencies": {
79
- "chalk": "^5.6.2",
80
73
  "es-toolkit": "^1.41.0",
81
74
  "pathe": "^2.0.3"
82
75
  },
83
- "gitHead": "7ef2b7ddf3c66a79d3d0af5e6f9653d7d7d02fdb"
76
+ "gitHead": "e6d6cd5dd4098fc9b4cf537b0dcdc7e781c0e80e"
84
77
  }
package/paths.ts CHANGED
@@ -8,24 +8,6 @@
8
8
  * - root* 系列:Core 框架内部路径(packages/core/*)
9
9
  * - project* 系列:用户项目路径(process.cwd()/*)
10
10
  *
11
- * 目录结构:
12
- * ```
13
- * packages/core/ (coreDir)
14
- * ├── scripts/ (coreScriptDir)
15
- * ├── config/ (coreConfigDir)
16
- * ├── checks/ (coreCheckDir)
17
- * ├── plugins/ (corePluginDir)
18
- * ├── apis/ (coreApiDir)
19
- * └── tables/ (coreTableDir)
20
- *
21
- * project/ (projectDir)
22
- * ├── scripts/ (projectScriptDir)
23
- * ├── config/ (projectConfigDir)
24
- * ├── checks/ (projectCheckDir)
25
- * ├── plugins/ (projectPluginDir)
26
- * ├── apis/ (projectApiDir)
27
- * └── tables/ (projectTableDir)
28
- * ```
29
11
  */
30
12
 
31
13
  import { fileURLToPath } from 'node:url';
@@ -35,9 +17,6 @@ import { dirname, join } from 'pathe';
35
17
  const __filename = fileURLToPath(import.meta.url);
36
18
  const __dirname = dirname(__filename);
37
19
 
38
- // 项目根目录(befly 框架的使用方项目)
39
- const projectRoot = process.cwd();
40
-
41
20
  // ==================== Core 框架路径 ====================
42
21
 
43
22
  /**
@@ -46,20 +25,6 @@ const projectRoot = process.cwd();
46
25
  */
47
26
  export const coreDir = __dirname;
48
27
 
49
- /**
50
- * Core 框架脚本目录
51
- * @description packages/core/scripts/
52
- * @usage 存放框架级别的脚本工具
53
- */
54
- export const coreScriptDir = join(__dirname, 'scripts');
55
-
56
- /**
57
- * Core 框架配置目录
58
- * @description packages/core/config/
59
- * @usage 存放框架默认配置(env.ts, fields.ts 等)
60
- */
61
- export const coreConfigDir = join(__dirname, 'config');
62
-
63
28
  /**
64
29
  * Core 框架检查目录
65
30
  * @description packages/core/checks/
@@ -95,46 +60,32 @@ export const coreTableDir = join(__dirname, 'tables');
95
60
  * @description process.cwd()
96
61
  * @usage 用户项目的根目录
97
62
  */
98
- export const projectDir = projectRoot;
99
-
100
- /**
101
- * 项目脚本目录
102
- * @description {projectDir}/scripts/
103
- * @usage 存放用户自定义脚本工具
104
- */
105
- export const projectScriptDir = join(projectRoot, 'scripts');
106
-
107
- /**
108
- * 项目配置目录
109
- * @description {projectDir}/config/
110
- * @usage 存放用户项目配置(覆盖框架默认配置)
111
- */
112
- export const projectConfigDir = join(projectRoot, 'config');
63
+ export const projectDir = process.cwd();
113
64
 
114
65
  /**
115
66
  * 项目检查目录
116
67
  * @description {projectDir}/checks/
117
68
  * @usage 存放用户自定义启动检查模块
118
69
  */
119
- export const projectCheckDir = join(projectRoot, 'checks');
70
+ export const projectCheckDir = join(projectDir, 'checks');
120
71
 
121
72
  /**
122
73
  * 项目插件目录
123
74
  * @description {projectDir}/plugins/
124
75
  * @usage 存放用户自定义插件
125
76
  */
126
- export const projectPluginDir = join(projectRoot, 'plugins');
77
+ export const projectPluginDir = join(projectDir, 'plugins');
127
78
 
128
79
  /**
129
80
  * 项目 API 目录
130
81
  * @description {projectDir}/apis/
131
82
  * @usage 存放用户业务 API 接口
132
83
  */
133
- export const projectApiDir = join(projectRoot, 'apis');
84
+ export const projectApiDir = join(projectDir, 'apis');
134
85
 
135
86
  /**
136
87
  * 项目表定义目录
137
88
  * @description {projectDir}/tables/
138
89
  * @usage 存放用户业务表定义(JSON 格式)
139
90
  */
140
- export const projectTableDir = join(projectRoot, 'tables');
91
+ export const projectTableDir = join(projectDir, 'tables');
package/plugins/db.ts CHANGED
@@ -24,7 +24,7 @@ const dbPlugin: Plugin = {
24
24
  if (Env.DB_ENABLE === 1) {
25
25
  // 创建 Bun SQL 客户端(内置连接池),并确保连接验证成功后再继续
26
26
  // 从环境变量读取连接超时配置
27
- const connectionTimeout = Env.DB_CONNECTION_TIMEOUT ? parseInt(Env.DB_CONNECTION_TIMEOUT) : 5000;
27
+ const connectionTimeout = Env.DB_CONNECTION_TIMEOUT ? parseInt(Env.DB_CONNECTION_TIMEOUT) : 30000;
28
28
 
29
29
  sql = await Database.connectSql({
30
30
  connectionTimeout
@@ -168,7 +168,7 @@ export interface SqlClientOptions {
168
168
  max?: number;
169
169
  /** 是否使用 BigInt */
170
170
  bigint?: boolean;
171
- /** 连接超时时间(毫秒),默认 5000ms */
171
+ /** 连接超时时间(毫秒),默认 30000ms */
172
172
  connectionTimeout?: number;
173
173
  /** 其他自定义选项 */
174
174
  [key: string]: any;
package/util.ts CHANGED
@@ -1,21 +1,4 @@
1
- /**
2
- * Befly 核心工具函数集合
3
- *
4
- * 本文件整合了框架核心工具函数:
5
- * - API 响应工具(Yes, No)
6
- * - 对象操作(pickFields, fieldClear)
7
- * - 日期时间(calcPerfTime)
8
- * - 表定义工具(parseRule)
9
- * - Addon 管理(scanAddons, getAddonDir 等)
10
- *
11
- * 注意:
12
- * - JWT 工具位于 lib/jwt.ts
13
- * - Logger 位于 lib/logger.ts
14
- * - Validator 位于 lib/validator.ts
15
- * - Database 管理位于 lib/database.ts
16
- */
17
-
18
- import fs from 'node:fs';
1
+ import fs from 'node:fs';
19
2
  import { join } from 'pathe';
20
3
  import { readdirSync, statSync, readFileSync, existsSync } from 'node:fs';
21
4
  import { isEmpty, isPlainObject } from 'es-toolkit/compat';
@@ -232,68 +215,3 @@ export const parseRule = (rule: string): ParsedFieldRule => {
232
215
  regex: fieldRegx !== 'null' ? fieldRegx : null
233
216
  };
234
217
  };
235
-
236
- // ========================================
237
- // Addon 管理工具
238
- // ========================================
239
-
240
- /**
241
- * 扫描所有可用的 addon
242
- */
243
- export const scanAddons = (): string[] => {
244
- const beflyDir = join(projectDir, 'node_modules', '@befly-addon');
245
-
246
- if (!existsSync(beflyDir)) {
247
- return [];
248
- }
249
-
250
- try {
251
- return fs
252
- .readdirSync(beflyDir)
253
- .filter((name) => {
254
- // addon 名称格式:admin, demo 等(不带 addon- 前缀)
255
- const fullPath = join(beflyDir, name);
256
- try {
257
- const stat = statSync(fullPath);
258
- return stat.isDirectory();
259
- } catch {
260
- return false;
261
- }
262
- })
263
- .sort();
264
- } catch {
265
- return [];
266
- }
267
- };
268
-
269
- /**
270
- * 获取 addon 的指定子目录路径
271
- */
272
- export const getAddonDir = (addonName: string, subDir: string): string => {
273
- return join(projectDir, 'node_modules', '@befly-addon', addonName, subDir);
274
- };
275
-
276
- /**
277
- * 检查 addon 子目录是否存在
278
- */
279
- export const addonDirExists = (addonName: string, subDir: string): boolean => {
280
- const dir = getAddonDir(addonName, subDir);
281
- return existsSync(dir) && statSync(dir).isDirectory();
282
- };
283
-
284
- /**
285
- * 获取插件目录列表
286
- * @param addonsDir - addons 根目录路径
287
- * @returns 插件名称数组
288
- */
289
- export function getAddonDirs(addonsDir: string): string[] {
290
- // try {
291
- return readdirSync(addonsDir).filter((name) => {
292
- const addonPath = path.join(addonsDir, name);
293
- return statSync(addonPath).isDirectory() && !name.startsWith('_');
294
- });
295
- // } catch (error: any) {
296
- // Logger.error(`读取插件目录失败: ${addonsDir}`, error.message);
297
- // return [];
298
- // }
299
- }
package/apis/admin/del.ts DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * 删除管理员
3
- */
4
-
5
- import { Yes, No } from '../../util.js';
6
-
7
- export default {
8
- name: '删除管理员',
9
- fields: {},
10
- required: ['id'],
11
- handler: async (befly, ctx) => {
12
- // 检查管理员是否存在
13
- const admin = await befly.db.getOne({
14
- table: 'core_admin',
15
- where: { id: ctx.body.id }
16
- });
17
-
18
- if (!admin) {
19
- return No('管理员不存在');
20
- }
21
-
22
- // 不能删除 dev 角色的管理员
23
- if (admin.roleCode === 'dev') {
24
- return No('不能删除开发者账号');
25
- }
26
-
27
- // 删除管理员
28
- await befly.db.delData({
29
- table: 'core_admin',
30
- where: { id: ctx.body.id }
31
- });
32
-
33
- return Yes('删除成功');
34
- }
35
- };