befly 2.3.3 → 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.js → table.ts} +139 -61
  6. package/config/env.ts +218 -0
  7. package/config/reserved.ts +96 -0
  8. package/main.ts +101 -0
  9. package/package.json +44 -8
  10. package/plugins/{db.js → db.ts} +24 -11
  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.js → syncDev.ts} +41 -25
  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/bin/befly.js +0 -109
  76. package/config/env.js +0 -64
  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 -752
  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 -334
  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 -226
@@ -1,31 +1,42 @@
1
1
  /**
2
- * 同步开发管理员账号脚本
3
- * - 账号: dev
2
+ * 同步开发者用户到数据库
3
+ * - 用户名: Env.DEV_USERNAME (默认 dev)
4
4
  * - 密码: Crypto2.hmacMd5(Crypto2.md5(Env.DEV_PASSWORD), Env.MD5_SALT)
5
- * - 行为: 若存在则更新密码与 updated_at;不存在则插入新记录
6
5
  */
7
6
 
7
+ import { DB } from '../plugins/db.js';
8
8
  import { Env } from '../config/env.js';
9
9
  import { Logger } from '../utils/logger.js';
10
- import { createSqlClient } from '../utils/index.js';
11
10
  import { Crypto2 } from '../utils/crypto.js';
11
+ import { createSqlClient } from '../utils/dbHelper.js';
12
12
 
13
- // 命令行参数(保持与 syncDb.js 一致的 plan 行为)
13
+ // CLI 参数类型
14
+ interface CliArgs {
15
+ DRY_RUN: boolean;
16
+ }
17
+
18
+ // 解析命令行参数
14
19
  const ARGV = Array.isArray(process.argv) ? process.argv : [];
15
- const CLI = { DRY_RUN: ARGV.includes('--plan') };
20
+ const CLI: CliArgs = { DRY_RUN: ARGV.includes('--plan') };
16
21
 
17
- // 执行器封装
18
- const exec = async (client, query, params = []) => {
19
- if (params && params.length > 0) return await client.unsafe(query, params);
22
+ /**
23
+ * 执行 SQL 查询
24
+ */
25
+ const exec = async (client: any, query: string, params: any[] = []): Promise<any> => {
26
+ if (params && params.length > 0) {
27
+ return await client.unsafe(query, params);
28
+ }
20
29
  return await client.unsafe(query);
21
30
  };
22
31
 
23
32
  /**
24
33
  * 同步开发管理员账号
25
- * @param {import('bun').SQL | null} client 可选,复用已有 SQL 客户端;不传则内部创建与关闭
34
+ * @param client 可选,复用已有 SQL 客户端;不传则内部创建与关闭
35
+ * @returns 是否成功
26
36
  */
27
- export async function SyncDev(client = null) {
37
+ export async function SyncDev(client: any = null): Promise<boolean> {
28
38
  let ownClient = false;
39
+
29
40
  try {
30
41
  if (CLI.DRY_RUN) {
31
42
  Logger.info('[计划] 同步完成后将初始化/更新 admin.dev 账号(plan 模式不执行)');
@@ -42,54 +53,59 @@ export async function SyncDev(client = null) {
42
53
  ownClient = true;
43
54
  }
44
55
 
45
- // 检查 admin 表是否存在
46
- const [exist] = await exec(client, 'SELECT COUNT(*) AS cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? LIMIT 1', [Env.DB_NAME || '', 'admin']);
47
- if (!exist || Number(exist.cnt) === 0) {
48
- Logger.warn('跳过开发管理员初始化:未检测到 admin 表');
56
+ // 检查 sys_admin 表是否存在(核心表带 sys_ 前缀)
57
+ const exist = await exec(client, 'SELECT COUNT(*) AS cnt FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? LIMIT 1', [Env.DB_NAME || '', 'sys_admin']);
58
+
59
+ if (!exist || !exist[0] || Number(exist[0].cnt) === 0) {
60
+ Logger.warn('跳过开发管理员初始化:未检测到 sys_admin 表');
49
61
  return false;
50
62
  }
51
63
 
52
64
  const nowTs = Date.now();
65
+ // 对密码进行双重加密
53
66
  const hashed = Crypto2.hmacMd5(Crypto2.md5(Env.DEV_PASSWORD), Env.MD5_SALT);
54
67
 
55
68
  // 更新存在的 dev 账号
56
- const updateRes = await exec(client, 'UPDATE `admin` SET `password` = ?, `updated_at` = ? WHERE `account` = ? LIMIT 1', [hashed, nowTs, 'dev']);
69
+ const updateRes = await exec(client, 'UPDATE `sys_admin` SET `password` = ?, `updated_at` = ? WHERE `account` = ? LIMIT 1', [hashed, nowTs, 'dev']);
70
+
57
71
  const affected = updateRes?.affectedRows ?? updateRes?.rowsAffected ?? 0;
58
72
 
59
73
  if (!affected || affected === 0) {
60
74
  // 插入新账号
61
75
  const id = nowTs;
62
- await exec(client, 'INSERT INTO `admin` (`id`, `created_at`, `updated_at`, `deleted_at`, `state`, `account`, `password`) VALUES (?, ?, ?, 0, 0, ?, ?)', [id, nowTs, nowTs, 'dev', hashed]);
76
+ await exec(client, 'INSERT INTO `sys_admin` (`id`, `created_at`, `updated_at`, `deleted_at`, `state`, `account`, `password`) VALUES (?, ?, ?, 0, 0, ?, ?)', [id, nowTs, nowTs, 'dev', hashed]);
63
77
  Logger.info('开发管理员已初始化:account=dev');
64
78
  } else {
65
79
  Logger.info('开发管理员已更新密码并刷新更新时间:account=dev');
66
80
  }
67
81
 
68
82
  return true;
69
- } catch (e) {
70
- Logger.warn(`开发管理员初始化步骤出错:${e.message}`);
83
+ } catch (error: any) {
84
+ Logger.warn(`开发管理员初始化步骤出错:${error.message}`);
71
85
  return false;
72
86
  } finally {
73
87
  if (ownClient && client) {
74
88
  try {
75
89
  await client.close();
76
- } catch (e) {
77
- Logger.warn('关闭数据库连接时出错:', e.message);
90
+ } catch (error: any) {
91
+ Logger.warn('关闭数据库连接时出错:', error.message);
78
92
  }
79
93
  }
80
94
  }
81
95
  }
82
96
 
83
- // 允许直接运行该脚本
84
- if (import.meta.url === `file://${process.argv[1]}`) {
97
+ /**
98
+ * 允许直接运行该脚本
99
+ */
100
+ if (import.meta.main) {
85
101
  SyncDev()
86
- .then((ok) => {
102
+ .then((ok: boolean) => {
87
103
  if (CLI.DRY_RUN) {
88
104
  process.exit(0);
89
105
  }
90
106
  process.exit(ok ? 0 : 1);
91
107
  })
92
- .catch((err) => {
108
+ .catch((err: Error) => {
93
109
  console.error('❌ 开发管理员同步失败:', err);
94
110
  process.exit(1);
95
111
  });
package/system.ts ADDED
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Befly 框架系统路径定义 - TypeScript 版本
3
+ * 提供统一的路径变量,供整个框架使用
4
+ */
5
+
6
+ import { fileURLToPath } from 'node:url';
7
+ import { dirname, join, resolve, relative } from 'node:path';
8
+
9
+ // 当前文件的路径信息
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+
13
+ // Befly 框架根目录
14
+ export const __dirroot = __dirname;
15
+
16
+ // 各个重要目录的路径
17
+ export const __dirscript = join(__dirroot, 'scripts');
18
+ export const __dirbin = join(__dirroot, 'bin');
19
+ export const __dirutils = join(__dirroot, 'utils');
20
+ export const __dirconfig = join(__dirroot, 'config');
21
+ export const __dirtables = join(__dirroot, 'tables');
22
+ export const __dirchecks = join(__dirroot, 'checks');
23
+ export const __dirapis = join(__dirroot, 'apis');
24
+ export const __dirplugins = join(__dirroot, 'plugins');
25
+ export const __dirlibs = join(__dirroot, 'libs');
26
+ export const __dirtests = join(__dirroot, 'tests');
27
+
28
+ /**
29
+ * 获取项目根目录(befly 框架的使用方项目)
30
+ */
31
+ export const getProjectRoot = (): string => {
32
+ return process.cwd();
33
+ };
34
+
35
+ /**
36
+ * 获取项目中的特定目录
37
+ * @param subdir - 子目录名称
38
+ */
39
+ export const getProjectDir = (subdir: string = ''): string => {
40
+ return subdir ? join(getProjectRoot(), subdir) : getProjectRoot();
41
+ };
42
+
43
+ /**
44
+ * 创建路径解析器,基于 befly 根目录
45
+ * @param paths - 路径片段
46
+ */
47
+ export const resolveBeflyPath = (...paths: string[]): string => {
48
+ return resolve(__dirroot, ...paths);
49
+ };
50
+
51
+ /**
52
+ * 创建路径解析器,基于项目根目录
53
+ * @param paths - 路径片段
54
+ */
55
+ export const resolveProjectPath = (...paths: string[]): string => {
56
+ return resolve(getProjectRoot(), ...paths);
57
+ };
58
+
59
+ /**
60
+ * 获取相对于 befly 根目录的相对路径
61
+ * @param targetPath - 目标路径
62
+ */
63
+ export const getRelativeBeflyPath = (targetPath: string): string => {
64
+ return relative(__dirroot, targetPath);
65
+ };
66
+
67
+ /**
68
+ * 获取相对于项目根目录的相对路径
69
+ * @param targetPath - 目标路径
70
+ */
71
+ export const getRelativeProjectPath = (targetPath: string): string => {
72
+ return relative(getProjectRoot(), targetPath);
73
+ };
74
+
75
+ /**
76
+ * 系统路径配置对象
77
+ */
78
+ export interface SystemPaths {
79
+ script: string;
80
+ bin: string;
81
+ utils: string;
82
+ config: string;
83
+ tables: string;
84
+ checks: string;
85
+ apis: string;
86
+ plugins: string;
87
+ libs: string;
88
+ tests: string;
89
+ }
90
+
91
+ /**
92
+ * 系统工具函数集合
93
+ */
94
+ export interface SystemUtils {
95
+ getProjectRoot: typeof getProjectRoot;
96
+ getProjectDir: typeof getProjectDir;
97
+ resolveBeflyPath: typeof resolveBeflyPath;
98
+ resolveProjectPath: typeof resolveProjectPath;
99
+ getRelativeBeflyPath: typeof getRelativeBeflyPath;
100
+ getRelativeProjectPath: typeof getRelativeProjectPath;
101
+ }
102
+
103
+ /**
104
+ * 系统配置对象
105
+ */
106
+ export interface SystemConfig {
107
+ __filename: string;
108
+ __dirname: string;
109
+ __dirroot: string;
110
+ paths: SystemPaths;
111
+ utils: SystemUtils;
112
+ }
113
+
114
+ /**
115
+ * 默认导出包含所有路径信息的对象
116
+ */
117
+ const system: SystemConfig = {
118
+ // 基础路径变量
119
+ __filename,
120
+ __dirname,
121
+ __dirroot,
122
+
123
+ // Befly 框架目录
124
+ paths: {
125
+ script: __dirscript,
126
+ bin: __dirbin,
127
+ utils: __dirutils,
128
+ config: __dirconfig,
129
+ tables: __dirtables,
130
+ checks: __dirchecks,
131
+ apis: __dirapis,
132
+ plugins: __dirplugins,
133
+ libs: __dirlibs,
134
+ tests: __dirtests
135
+ },
136
+
137
+ // 工具函数
138
+ utils: {
139
+ getProjectRoot,
140
+ getProjectDir,
141
+ resolveBeflyPath,
142
+ resolveProjectPath,
143
+ getRelativeBeflyPath,
144
+ getRelativeProjectPath
145
+ }
146
+ };
147
+
148
+ // 重新导出基础路径变量和 system 对象
149
+ export { __filename, __dirname, system };
@@ -0,0 +1,21 @@
1
+ {
2
+ "id": "ID|number|1|null|null|1|null",
3
+ "email": "邮箱|string|5|100|null|1|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
4
+ "phone": "手机号|string|11|11|null|1|^1[3-9]\\d{9}$",
5
+ "page": "页码|number|1|9999|1|0|null",
6
+ "limit": "每页数量|number|1|100|10|0|null",
7
+ "title": "标题|string|1|200|null|0|null",
8
+ "description": "描述|string|0|500|null|0|null",
9
+ "keyword": "关键词|string|1|50|null|1|null",
10
+ "keywords": "关键词列表|array|0|50|null|0|null",
11
+ "enabled": "启用状态|number|0|1|1|0|^(0|1)$",
12
+ "date": "日期|string|10|10|null|0|^\\d{4}-\\d{2}-\\d{2}$",
13
+ "datetime": "日期时间|string|19|25|null|0|^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}",
14
+ "filename": "文件名|string|1|255|null|0|null",
15
+ "url": "网址|string|5|500|null|0|^https?://",
16
+ "tag": "标签|array|0|10|null|0|null",
17
+ "orderBy": "排序字段|array|0|20|null|0|null",
18
+ "where": "查询条件|object|null|null|null|0|null",
19
+ "startTime": "开始时间|number|0|9999999999999|null|0|null",
20
+ "endTime": "结束时间|number|0|9999999999999|null|0|null"
21
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "account": "账号|string|3|50|null|1|^[a-zA-Z0-9_]+$",
3
+ "password": "密码|string|32|255|null|0|null",
4
+ "nickname": "昵称|string|0|50|null|0|null",
5
+ "avatar": "头像|string|0|500|null|0|null",
6
+ "email": "邮箱|string|0|100|null|0|^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
7
+ "phone": "手机号|string|0|11|null|0|^1[3-9]\\d{9}$",
8
+ "role": "角色|string|1|20|admin|1|^(superadmin|admin|user)$",
9
+ "status": "状态|number|0|1|1|1|^(0|1)$"
10
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "compilerOptions": {
3
+ // 基础配置
4
+ "target": "ESNext",
5
+ "module": "ESNext",
6
+ "lib": ["ESNext"],
7
+ "moduleResolution": "bundler",
8
+
9
+ // 类型检查
10
+ "strict": true,
11
+ "noImplicitAny": true,
12
+ "strictNullChecks": true,
13
+ "strictFunctionTypes": true,
14
+ "strictBindCallApply": true,
15
+ "strictPropertyInitialization": true,
16
+ "noImplicitThis": true,
17
+ "alwaysStrict": true,
18
+
19
+ // 额外检查
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
+ "noImplicitReturns": true,
23
+ "noFallthroughCasesInSwitch": true,
24
+ "noUncheckedIndexedAccess": false,
25
+ "noImplicitOverride": true,
26
+ "noPropertyAccessFromIndexSignature": false,
27
+
28
+ // 模块
29
+ "esModuleInterop": true,
30
+ "allowSyntheticDefaultImports": true,
31
+ "forceConsistentCasingInFileNames": true,
32
+ "resolveJsonModule": true,
33
+ "isolatedModules": true,
34
+
35
+ // 输出
36
+ "declaration": true,
37
+ "declarationMap": true,
38
+ "sourceMap": true,
39
+ "removeComments": false,
40
+ "importHelpers": false,
41
+
42
+ // 高级
43
+ "skipLibCheck": true,
44
+ "allowJs": true,
45
+ "checkJs": false,
46
+
47
+ // Bun 特定
48
+ "types": ["bun-types"],
49
+
50
+ // 路径
51
+ "baseUrl": ".",
52
+ "paths": {
53
+ "@/*": ["./*"]
54
+ }
55
+ },
56
+ "include": ["**/*.ts", "**/*.js"],
57
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.js"]
58
+ }
package/types/api.d.ts ADDED
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Befly API 类型定义
3
+ */
4
+
5
+ import type { BeflyContext } from './befly.js';
6
+ import type { KeyValue, TableDefinition } from './common.js';
7
+ import type { RequestContext } from './context.js';
8
+
9
+ /**
10
+ * HTTP 方法类型
11
+ */
12
+ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
13
+
14
+ /**
15
+ * 请求上下文类型(已废弃,使用 RequestContext 类)
16
+ * @deprecated 使用 RequestContext 类替代
17
+ */
18
+ export interface RequestContext<T = any> {
19
+ /** 请求对象 */
20
+ request: Request;
21
+
22
+ /** 请求体参数 */
23
+ body: T;
24
+
25
+ /** URL 参数 */
26
+ query: KeyValue<string>;
27
+
28
+ /** 路径参数 */
29
+ pathParams: KeyValue<string>;
30
+
31
+ /** 请求头 */
32
+ headers: Headers;
33
+
34
+ /** 用户信息(认证后) */
35
+ user?: UserInfo;
36
+
37
+ /** 客户端 IP */
38
+ ip?: string;
39
+
40
+ /** User-Agent */
41
+ userAgent?: string;
42
+
43
+ /** 请求 ID */
44
+ requestId?: string;
45
+
46
+ /** 开始时间 */
47
+ startTime: number;
48
+ }
49
+
50
+ /**
51
+ * 用户信息类型
52
+ */
53
+ export interface UserInfo {
54
+ id: number;
55
+ username?: string;
56
+ email?: string;
57
+ role?: string;
58
+ [key: string]: any;
59
+ }
60
+
61
+ /**
62
+ * 认证类型
63
+ * - false: 不需要认证
64
+ * - true: 需要认证(验证 token)
65
+ * - 'admin': 需要管理员权限
66
+ * - 'user': 需要普通用户权限
67
+ * - string[]: 需要特定角色
68
+ */
69
+ export type AuthType = boolean | 'admin' | 'user' | string[];
70
+
71
+ /**
72
+ * API 处理器函数类型
73
+ */
74
+ export type ApiHandler<T = any, R = any> = (befly: BeflyContext, ctx: RequestContext, req?: Request) => Promise<Response | R> | Response | R;
75
+
76
+ /**
77
+ * 字段规则定义
78
+ * 键为字段名,值为字段规则字符串
79
+ */
80
+ export type FieldRules = Record<string, string>;
81
+
82
+ /**
83
+ * API 配置选项
84
+ */
85
+ export interface ApiOptions {
86
+ /** HTTP 方法 */
87
+ method: HttpMethod;
88
+ /** 是否需要认证(true/false/角色数组) */
89
+ auth?: boolean | string[];
90
+ /** 字段规则 */
91
+ fields?: FieldRules;
92
+ /** 必填字段 */
93
+ required?: string[];
94
+ /** 处理函数 */
95
+ handler: ApiHandler;
96
+ }
97
+
98
+ /**
99
+ * API 路由配置
100
+ */
101
+ export interface ApiRoute<T = any, R = any> {
102
+ /** HTTP 方法 */
103
+ method: HttpMethod;
104
+
105
+ /** 接口名称 */
106
+ name: string;
107
+
108
+ /** 路由路径(运行时生成) */
109
+ route?: string;
110
+
111
+ /** 认证类型 */
112
+ auth: boolean | string | string[];
113
+
114
+ /** 字段定义(验证规则) */
115
+ fields: TableDefinition;
116
+
117
+ /** 必填字段 */
118
+ required: string[];
119
+
120
+ /** 处理器函数 */
121
+ handler: ApiHandler<T, R>;
122
+ }
123
+
124
+ /**
125
+ * API 构建器接口
126
+ */
127
+ export interface ApiBuilder {
128
+ /** 设置 HTTP 方法 */
129
+ method(method: HttpMethod): this;
130
+
131
+ /** 设置路径 */
132
+ path(path: string): this;
133
+
134
+ /** 设置描述 */
135
+ description(desc: string): this;
136
+
137
+ /** 设置认证 */
138
+ auth(auth: AuthType): this;
139
+
140
+ /** 设置验证规则 */
141
+ rules(rules: KeyValue<string>): this;
142
+
143
+ /** 设置必填字段 */
144
+ required(fields: string[]): this;
145
+
146
+ /** 设置处理器 */
147
+ handler(handler: ApiHandler): this;
148
+
149
+ /** 构建路由 */
150
+ build(): ApiRoute;
151
+ }
152
+
153
+ /**
154
+ * API 响应辅助函数
155
+ */
156
+ export interface ApiResponse {
157
+ /** 成功响应 */
158
+ success<T = any>(message: string, data?: T): Response;
159
+
160
+ /** 失败响应 */
161
+ error(message: string, error?: any): Response;
162
+
163
+ /** JSON 响应 */
164
+ json<T = any>(data: T, status?: number): Response;
165
+
166
+ /** 文本响应 */
167
+ text(text: string, status?: number): Response;
168
+
169
+ /** HTML 响应 */
170
+ html(html: string, status?: number): Response;
171
+
172
+ /** 重定向 */
173
+ redirect(url: string, status?: number): Response;
174
+ }
175
+
176
+ /**
177
+ * 路由匹配结果
178
+ */
179
+ export interface RouteMatch {
180
+ /** 路由配置 */
181
+ route: ApiRoute;
182
+
183
+ /** 路径参数 */
184
+ params: KeyValue<string>;
185
+ }
186
+
187
+ /**
188
+ * 路由器接口
189
+ */
190
+ export interface Router {
191
+ /** 添加路由 */
192
+ add(route: ApiRoute): void;
193
+
194
+ /** 匹配路由 */
195
+ match(method: HttpMethod, path: string): RouteMatch | null;
196
+
197
+ /** 获取所有路由 */
198
+ getRoutes(): ApiRoute[];
199
+
200
+ /** 删除路由 */
201
+ remove(method: HttpMethod, path: string): boolean;
202
+ }
203
+
204
+ // ========== API 响应数据类型 ==========
205
+
206
+ /**
207
+ * 令牌检测响应数据
208
+ */
209
+ export interface TokenCheckData {
210
+ /** 令牌是否有效 */
211
+ valid: boolean;
212
+ /** JWT 载荷(有效时返回) */
213
+ payload?: any;
214
+ /** 过期时间(秒) */
215
+ expiresIn?: number;
216
+ }
217
+
218
+ /**
219
+ * 健康检查响应数据
220
+ */
221
+ export interface HealthInfo {
222
+ /** 服务状态 */
223
+ status: string;
224
+ /** 时间戳 */
225
+ timestamp: string;
226
+ /** 运行时长(秒) */
227
+ uptime: number;
228
+ /** 内存使用情况 */
229
+ memory: NodeJS.MemoryUsage;
230
+ /** 运行时名称 */
231
+ runtime: string;
232
+ /** 版本号 */
233
+ version: string;
234
+ /** 平台 */
235
+ platform: string;
236
+ /** 架构 */
237
+ arch: string;
238
+ /** Redis 状态 */
239
+ redis?: string;
240
+ /** Redis 错误信息 */
241
+ redisError?: string;
242
+ /** 数据库状态 */
243
+ database?: string;
244
+ /** 数据库错误信息 */
245
+ databaseError?: string;
246
+ }