befly 3.8.30 → 3.8.31
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/README.md +83 -0
- package/checks/checkApp.ts +31 -1
- package/hooks/cors.ts +3 -3
- package/hooks/parser.ts +3 -3
- package/hooks/validator.ts +1 -1
- package/lib/cacheHelper.ts +0 -6
- package/lib/cipher.ts +2 -1
- package/lib/connect.ts +17 -19
- package/lib/jwt.ts +1 -1
- package/lib/logger.ts +1 -1
- package/lib/validator.ts +149 -384
- package/loader/loadHooks.ts +4 -3
- package/loader/loadPlugins.ts +7 -9
- package/main.ts +22 -36
- package/package.json +4 -3
- package/plugins/cipher.ts +1 -1
- package/plugins/config.ts +3 -4
- package/plugins/db.ts +4 -5
- package/plugins/jwt.ts +3 -2
- package/plugins/logger.ts +6 -6
- package/plugins/redis.ts +8 -12
- package/router/static.ts +3 -6
- package/sync/syncAll.ts +7 -12
- package/sync/syncApi.ts +4 -3
- package/sync/syncDb.ts +6 -5
- package/sync/syncDev.ts +9 -8
- package/sync/syncMenu.ts +174 -132
- package/tests/integration.test.ts +2 -6
- package/tests/redisHelper.test.ts +1 -2
- package/tests/validator.test.ts +611 -85
- package/types/befly.d.ts +7 -0
- package/types/cache.d.ts +73 -0
- package/types/common.d.ts +1 -37
- package/types/database.d.ts +5 -0
- package/types/index.ts +5 -5
- package/types/plugin.d.ts +1 -4
- package/types/redis.d.ts +37 -2
- package/types/table.d.ts +6 -44
- package/config.ts +0 -70
- package/tests/validator-advanced.test.ts +0 -653
- package/types/addon.d.ts +0 -50
- package/types/crypto.d.ts +0 -23
- package/types/jwt.d.ts +0 -99
- package/types/logger.d.ts +0 -13
- package/types/tool.d.ts +0 -67
- package/types/validator.d.ts +0 -43
package/types/befly.d.ts
CHANGED
|
@@ -124,6 +124,13 @@ export interface BeflyOptions {
|
|
|
124
124
|
disableHooks?: string[];
|
|
125
125
|
/** 禁用的插件列表 */
|
|
126
126
|
disablePlugins?: string[];
|
|
127
|
+
/** 隐藏的菜单路径列表(不同步到数据库) */
|
|
128
|
+
hiddenMenus?: string[];
|
|
129
|
+
/**
|
|
130
|
+
* Addon 运行时配置
|
|
131
|
+
* 按 addon 名称分组,如 addons.admin.email
|
|
132
|
+
*/
|
|
133
|
+
addons?: Record<string, Record<string, any>>;
|
|
127
134
|
/** 其他插件配置 */
|
|
128
135
|
[key: string]: any;
|
|
129
136
|
}
|
package/types/cache.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 缓存助手类型定义
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { BeflyContext } from './befly.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 缓存助手类
|
|
9
|
+
* 负责在服务器启动时缓存接口、菜单和角色权限到 Redis
|
|
10
|
+
*/
|
|
11
|
+
export interface CacheHelper {
|
|
12
|
+
/**
|
|
13
|
+
* 缓存所有接口到 Redis
|
|
14
|
+
*/
|
|
15
|
+
cacheApis(): Promise<void>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 缓存所有菜单到 Redis(从数据库读取)
|
|
19
|
+
*/
|
|
20
|
+
cacheMenus(): Promise<void>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 缓存所有角色的接口权限到 Redis
|
|
24
|
+
* 优化:使用 Promise.all 利用 Bun Redis 自动 pipeline 特性
|
|
25
|
+
*/
|
|
26
|
+
cacheRolePermissions(): Promise<void>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 缓存所有数据(接口、菜单、角色权限)
|
|
30
|
+
*/
|
|
31
|
+
cacheAll(): Promise<void>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 获取缓存的所有接口
|
|
35
|
+
* @returns 接口列表
|
|
36
|
+
*/
|
|
37
|
+
getApis(): Promise<any[]>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 获取缓存的所有菜单
|
|
41
|
+
* @returns 菜单列表
|
|
42
|
+
*/
|
|
43
|
+
getMenus(): Promise<any[]>;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 获取角色的接口权限
|
|
47
|
+
* @param roleCode - 角色代码
|
|
48
|
+
* @returns 接口路径列表
|
|
49
|
+
*/
|
|
50
|
+
getRolePermissions(roleCode: string): Promise<string[]>;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 检查角色是否有指定接口权限
|
|
54
|
+
* @param roleCode - 角色代码
|
|
55
|
+
* @param apiPath - 接口路径(格式:METHOD/path)
|
|
56
|
+
* @returns 是否有权限
|
|
57
|
+
*/
|
|
58
|
+
checkRolePermission(roleCode: string, apiPath: string): Promise<boolean>;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* 删除角色的接口权限缓存
|
|
62
|
+
* @param roleCode - 角色代码
|
|
63
|
+
* @returns 是否删除成功
|
|
64
|
+
*/
|
|
65
|
+
deleteRolePermissions(roleCode: string): Promise<boolean>;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* CacheHelper 构造函数类型
|
|
70
|
+
*/
|
|
71
|
+
export interface CacheHelperConstructor {
|
|
72
|
+
new (befly: BeflyContext): CacheHelper;
|
|
73
|
+
}
|
package/types/common.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Befly 框架通用类型定义
|
|
3
|
-
* Core
|
|
3
|
+
* Core 专用类型,通用类型请直接从 befly-shared/types 导入
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type { SqlValue } from 'befly-shared/types';
|
|
7
|
-
|
|
8
6
|
// ============================================
|
|
9
7
|
// Core 专用类型(不适合放在 shared 中的类型)
|
|
10
8
|
// ============================================
|
|
@@ -45,22 +43,6 @@ export type ComparisonOperator = '=' | '>' | '<' | '>=' | '<=' | '!=' | '<>' | '
|
|
|
45
43
|
*/
|
|
46
44
|
export type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'FULL';
|
|
47
45
|
|
|
48
|
-
/**
|
|
49
|
-
* 日志级别
|
|
50
|
-
*/
|
|
51
|
-
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* 日志配置
|
|
55
|
-
*/
|
|
56
|
-
export interface LoggerConfig {
|
|
57
|
-
level?: LogLevel;
|
|
58
|
-
transport?: {
|
|
59
|
-
target: string;
|
|
60
|
-
options?: Record<string, any>;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
|
|
64
46
|
/**
|
|
65
47
|
* 工具函数返回类型
|
|
66
48
|
*/
|
|
@@ -70,14 +52,6 @@ export interface ToolResponse<T = any> {
|
|
|
70
52
|
error?: string;
|
|
71
53
|
}
|
|
72
54
|
|
|
73
|
-
/**
|
|
74
|
-
* 分页参数
|
|
75
|
-
*/
|
|
76
|
-
export interface PaginationParams {
|
|
77
|
-
page: number;
|
|
78
|
-
limit: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
55
|
/**
|
|
82
56
|
* 可选字段
|
|
83
57
|
*/
|
|
@@ -88,16 +62,6 @@ export type Optional<T> = T | null | undefined;
|
|
|
88
62
|
*/
|
|
89
63
|
export type DeepPartial<T> = T extends object ? { [P in keyof T]?: DeepPartial<T[P]> } : T;
|
|
90
64
|
|
|
91
|
-
/**
|
|
92
|
-
* 保留字段(系统自动管理)
|
|
93
|
-
*/
|
|
94
|
-
export type ReservedFields = 'id' | 'created_at' | 'updated_at' | 'deleted_at' | 'state';
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* 排除保留字段
|
|
98
|
-
*/
|
|
99
|
-
export type ExcludeReserved<T> = Omit<T, ReservedFields>;
|
|
100
|
-
|
|
101
65
|
/**
|
|
102
66
|
* 数据库记录基础类型
|
|
103
67
|
*/
|
package/types/database.d.ts
CHANGED
|
@@ -369,6 +369,11 @@ export interface DbHelper {
|
|
|
369
369
|
* 查询单个字段值
|
|
370
370
|
*/
|
|
371
371
|
getFieldValue<T = any>(options: Omit<QueryOptions, 'fields'> & { field: string }): Promise<T | null>;
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* 清理数据或 where 条件(默认排除 null 和 undefined)
|
|
375
|
+
*/
|
|
376
|
+
cleanFields<T extends Record<string, any>>(data: T, excludeValues?: any[], keepValues?: Record<string, any>): Partial<T>;
|
|
372
377
|
}
|
|
373
378
|
|
|
374
379
|
/**
|
package/types/index.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 类型定义导出
|
|
3
|
+
*
|
|
4
|
+
* 注意:通用类型已迁移到 befly-shared/types
|
|
5
|
+
* - addon, crypto, jwt, logger, tool 等类型请从 befly-shared/types 导入
|
|
3
6
|
*/
|
|
4
7
|
|
|
5
|
-
export * from './addon.js';
|
|
6
8
|
export * from './api.js';
|
|
7
9
|
export * from './befly.js';
|
|
10
|
+
export * from './cache.js';
|
|
8
11
|
export * from './common.js';
|
|
9
12
|
export * from './context.js';
|
|
10
|
-
export * from './crypto.js';
|
|
11
13
|
export * from './database.js';
|
|
12
|
-
export * from './
|
|
13
|
-
export * from './logger.js';
|
|
14
|
+
export * from './hook.js';
|
|
14
15
|
export * from './plugin.js';
|
|
15
16
|
export * from './redis.js';
|
|
16
17
|
export * from './table.js';
|
|
17
|
-
export * from './tool.js';
|
|
18
18
|
export * from './validator.js';
|
|
19
19
|
export * from './sync.js';
|
package/types/plugin.d.ts
CHANGED
|
@@ -28,14 +28,11 @@ export interface Plugin {
|
|
|
28
28
|
after?: string[];
|
|
29
29
|
|
|
30
30
|
/** 插件初始化函数 */
|
|
31
|
-
handler?: (context: BeflyContext
|
|
31
|
+
handler?: (context: BeflyContext) => any | Promise<any>;
|
|
32
32
|
|
|
33
33
|
/** @deprecated use handler instead */
|
|
34
34
|
onInit?: PluginInitFunction;
|
|
35
35
|
|
|
36
|
-
/** 插件配置 */
|
|
37
|
-
config?: Record<string, any>;
|
|
38
|
-
|
|
39
36
|
/** 插件描述 */
|
|
40
37
|
description?: string;
|
|
41
38
|
|
package/types/redis.d.ts
CHANGED
|
@@ -23,14 +23,13 @@ export type RedisTTL = number | null;
|
|
|
23
23
|
* Redis 助手接口
|
|
24
24
|
*/
|
|
25
25
|
export interface RedisHelper {
|
|
26
|
+
// ==================== 基础操作 ====================
|
|
26
27
|
/** 设置对象到 Redis */
|
|
27
28
|
setObject<T = any>(key: string, obj: T, ttl?: RedisTTL): Promise<string | null>;
|
|
28
29
|
/** 从 Redis 获取对象 */
|
|
29
30
|
getObject<T = any>(key: string): Promise<T | null>;
|
|
30
31
|
/** 从 Redis 删除对象 */
|
|
31
32
|
delObject(key: string): Promise<void>;
|
|
32
|
-
/** 生成基于时间的唯一 ID */
|
|
33
|
-
genTimeID(): Promise<number>;
|
|
34
33
|
/** 设置字符串值 */
|
|
35
34
|
setString(key: string, value: string, ttl?: RedisTTL): Promise<string | null>;
|
|
36
35
|
/** 获取字符串值 */
|
|
@@ -41,6 +40,42 @@ export interface RedisHelper {
|
|
|
41
40
|
expire(key: string, seconds: number): Promise<number>;
|
|
42
41
|
/** 获取剩余过期时间 */
|
|
43
42
|
ttl(key: string): Promise<number>;
|
|
43
|
+
/** 删除键 */
|
|
44
|
+
del(key: string): Promise<number>;
|
|
44
45
|
/** 测试 Redis 连接 */
|
|
45
46
|
ping(): Promise<string>;
|
|
47
|
+
|
|
48
|
+
// ==================== ID 生成 ====================
|
|
49
|
+
/** 生成基于时间的唯一 ID (14位纯数字) */
|
|
50
|
+
genTimeID(): Promise<number>;
|
|
51
|
+
/** 批量生成基于时间的唯一 ID */
|
|
52
|
+
genTimeIDBatch(count: number): Promise<number[]>;
|
|
53
|
+
|
|
54
|
+
// ==================== Set 操作 ====================
|
|
55
|
+
/** 向 Set 中添加一个或多个成员 */
|
|
56
|
+
sadd(key: string, members: string[]): Promise<number>;
|
|
57
|
+
/** 判断成员是否在 Set 中 */
|
|
58
|
+
sismember(key: string, member: string): Promise<number>;
|
|
59
|
+
/** 获取 Set 的成员数量 */
|
|
60
|
+
scard(key: string): Promise<number>;
|
|
61
|
+
/** 获取 Set 的所有成员 */
|
|
62
|
+
smembers(key: string): Promise<string[]>;
|
|
63
|
+
|
|
64
|
+
// ==================== 批量操作 ====================
|
|
65
|
+
/** 批量设置对象 */
|
|
66
|
+
setBatch<T = any>(items: Array<{ key: string; value: T; ttl?: number | null }>): Promise<number>;
|
|
67
|
+
/** 批量获取对象 */
|
|
68
|
+
getBatch<T = any>(keys: string[]): Promise<Array<T | null>>;
|
|
69
|
+
/** 批量删除键 */
|
|
70
|
+
delBatch(keys: string[]): Promise<number>;
|
|
71
|
+
/** 批量检查键是否存在 */
|
|
72
|
+
existsBatch(keys: string[]): Promise<boolean[]>;
|
|
73
|
+
/** 批量设置过期时间 */
|
|
74
|
+
expireBatch(items: Array<{ key: string; seconds: number }>): Promise<number>;
|
|
75
|
+
/** 批量获取剩余过期时间 */
|
|
76
|
+
ttlBatch(keys: string[]): Promise<number[]>;
|
|
77
|
+
/** 批量向多个 Set 添加成员 */
|
|
78
|
+
saddBatch(items: Array<{ key: string; members: string[] }>): Promise<number>;
|
|
79
|
+
/** 批量检查成员是否在 Set 中 */
|
|
80
|
+
sismemberBatch(items: Array<{ key: string; member: string }>): Promise<boolean[]>;
|
|
46
81
|
}
|
package/types/table.d.ts
CHANGED
|
@@ -1,50 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 表类型定义 - 用于增强 DbHelper 泛型推断
|
|
3
|
+
*
|
|
4
|
+
* 基础类型(SystemFields, BaseTable, InsertType, UpdateType, SelectType)
|
|
5
|
+
* 请直接从 befly-shared/types 导入
|
|
3
6
|
*/
|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
// 基础表类型
|
|
7
|
-
// ============================================
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 系统字段(所有表都有的字段)
|
|
11
|
-
*/
|
|
12
|
-
export interface SystemFields {
|
|
13
|
-
/** 主键 ID(雪花 ID) */
|
|
14
|
-
id: number;
|
|
15
|
-
/** 状态:0=已删除, 1=正常, 2=禁用 */
|
|
16
|
-
state: number;
|
|
17
|
-
/** 创建时间(毫秒时间戳) */
|
|
18
|
-
createdAt: number;
|
|
19
|
-
/** 更新时间(毫秒时间戳) */
|
|
20
|
-
updatedAt: number;
|
|
21
|
-
/** 删除时间(毫秒时间戳,软删除时设置) */
|
|
22
|
-
deletedAt: number | null;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 基础表类型(包含系统字段)
|
|
27
|
-
*/
|
|
28
|
-
export type BaseTable<T extends Record<string, any>> = T & SystemFields;
|
|
29
|
-
|
|
30
|
-
// ============================================
|
|
31
|
-
// 表操作类型工具
|
|
32
|
-
// ============================================
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* 插入类型:排除系统自动生成的字段
|
|
36
|
-
*/
|
|
37
|
-
export type InsertType<T> = Omit<T, keyof SystemFields>;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 更新类型:所有字段可选,排除不可修改的系统字段
|
|
41
|
-
*/
|
|
42
|
-
export type UpdateType<T> = Partial<Omit<T, 'id' | 'createdAt' | 'updatedAt' | 'deletedAt'>>;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* 查询结果类型:完整的表记录
|
|
46
|
-
*/
|
|
47
|
-
export type SelectType<T> = T;
|
|
8
|
+
import type { BaseTable, InsertType, UpdateType } from 'befly-shared/types';
|
|
48
9
|
|
|
49
10
|
// ============================================
|
|
50
11
|
// 数据库表映射接口
|
|
@@ -205,7 +166,8 @@ export type TypedWhereConditions<T> = Partial<T> & // 精确匹配
|
|
|
205
166
|
ArrayConditions<T> & // 数组操作符
|
|
206
167
|
StringConditions<T> & // 字符串操作符
|
|
207
168
|
RangeConditions<T> & // 范围操作符
|
|
208
|
-
NullConditions<T> & {
|
|
169
|
+
NullConditions<T> & {
|
|
170
|
+
// 空值操作符
|
|
209
171
|
/** OR 条件组 */
|
|
210
172
|
$or?: TypedWhereConditions<T>[];
|
|
211
173
|
/** AND 条件组 */
|
package/config.ts
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Befly 默认配置
|
|
3
|
-
* 包含所有配置项的默认值
|
|
4
|
-
*/
|
|
5
|
-
import type { BeflyOptions } from './types/befly.js';
|
|
6
|
-
|
|
7
|
-
export const defaultOptions: Required<Omit<BeflyOptions, 'devPassword'>> = {
|
|
8
|
-
// ========== 核心参数 ==========
|
|
9
|
-
nodeEnv: (process.env.NODE_ENV as any) || 'development',
|
|
10
|
-
appName: '野蜂飞舞',
|
|
11
|
-
appPort: 3000,
|
|
12
|
-
appHost: '127.0.0.1',
|
|
13
|
-
devEmail: 'dev@qq.com',
|
|
14
|
-
devPassword: 'beflydev123456',
|
|
15
|
-
bodyLimit: 1048576, // 1MB
|
|
16
|
-
tz: 'Asia/Shanghai',
|
|
17
|
-
|
|
18
|
-
// ========== 日志配置 ==========
|
|
19
|
-
logger: {
|
|
20
|
-
debug: 1,
|
|
21
|
-
excludeFields: 'password,token,secret',
|
|
22
|
-
dir: './logs',
|
|
23
|
-
console: 1,
|
|
24
|
-
maxSize: 10485760 // 10MB
|
|
25
|
-
},
|
|
26
|
-
|
|
27
|
-
// ========== 数据库配置 ==========
|
|
28
|
-
db: {
|
|
29
|
-
type: 'mysql',
|
|
30
|
-
host: '127.0.0.1',
|
|
31
|
-
port: 3306,
|
|
32
|
-
username: 'root',
|
|
33
|
-
password: 'root',
|
|
34
|
-
database: 'befly_demo',
|
|
35
|
-
poolMax: 10
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
// ========== Redis 配置 ==========
|
|
39
|
-
redis: {
|
|
40
|
-
host: '127.0.0.1',
|
|
41
|
-
port: 6379,
|
|
42
|
-
username: '',
|
|
43
|
-
password: '',
|
|
44
|
-
db: 0,
|
|
45
|
-
prefix: 'befly_demo:'
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
// ========== 认证配置 ==========
|
|
49
|
-
auth: {
|
|
50
|
-
secret: 'befly-secret',
|
|
51
|
-
expiresIn: '7d',
|
|
52
|
-
algorithm: 'HS256'
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
// ========== CORS 配置 ==========
|
|
56
|
-
cors: {
|
|
57
|
-
origin: '*',
|
|
58
|
-
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
|
|
59
|
-
allowedHeaders: 'Content-Type,Authorization',
|
|
60
|
-
exposedHeaders: '',
|
|
61
|
-
maxAge: 86400,
|
|
62
|
-
credentials: 'true'
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
// ========== 禁用配置 ==========
|
|
66
|
-
/** 禁用的钩子列表 */
|
|
67
|
-
disableHooks: [],
|
|
68
|
-
/** 禁用的插件列表 */
|
|
69
|
-
disablePlugins: []
|
|
70
|
-
};
|