befly-shared 1.1.1

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 (76) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +442 -0
  3. package/dist/addonHelper.js +83 -0
  4. package/dist/arrayKeysToCamel.js +18 -0
  5. package/dist/arrayToTree.js +23 -0
  6. package/dist/calcPerfTime.js +13 -0
  7. package/dist/configTypes.js +1 -0
  8. package/dist/defineAddonConfig.js +40 -0
  9. package/dist/fieldClear.js +57 -0
  10. package/dist/genShortId.js +12 -0
  11. package/dist/index.js +25 -0
  12. package/dist/keysToCamel.js +21 -0
  13. package/dist/keysToSnake.js +21 -0
  14. package/dist/layouts.js +59 -0
  15. package/dist/pickFields.js +16 -0
  16. package/dist/redisKeys.js +34 -0
  17. package/dist/regex.js +200 -0
  18. package/dist/scanConfig.js +82 -0
  19. package/dist/scanFiles.js +39 -0
  20. package/dist/scanViews.js +48 -0
  21. package/dist/types.js +46 -0
  22. package/package.json +40 -0
  23. package/src/addonHelper.ts +88 -0
  24. package/src/arrayKeysToCamel.ts +18 -0
  25. package/src/arrayToTree.ts +31 -0
  26. package/src/calcPerfTime.ts +13 -0
  27. package/src/configTypes.ts +27 -0
  28. package/src/defineAddonConfig.ts +45 -0
  29. package/src/fieldClear.ts +75 -0
  30. package/src/genShortId.ts +12 -0
  31. package/src/index.ts +28 -0
  32. package/src/keysToCamel.ts +22 -0
  33. package/src/keysToSnake.ts +22 -0
  34. package/src/layouts.ts +90 -0
  35. package/src/pickFields.ts +19 -0
  36. package/src/redisKeys.ts +44 -0
  37. package/src/regex.ts +223 -0
  38. package/src/scanConfig.ts +104 -0
  39. package/src/scanFiles.ts +49 -0
  40. package/src/scanViews.ts +55 -0
  41. package/src/types.ts +338 -0
  42. package/tests/addonHelper.test.ts +55 -0
  43. package/tests/arrayKeysToCamel.test.ts +21 -0
  44. package/tests/arrayToTree.test.ts +98 -0
  45. package/tests/calcPerfTime.test.ts +19 -0
  46. package/tests/fieldClear.test.ts +39 -0
  47. package/tests/keysToCamel.test.ts +22 -0
  48. package/tests/keysToSnake.test.ts +22 -0
  49. package/tests/layouts.test.ts +93 -0
  50. package/tests/pickFields.test.ts +22 -0
  51. package/tests/regex.test.ts +308 -0
  52. package/tests/scanFiles.test.ts +58 -0
  53. package/tests/types.test.ts +283 -0
  54. package/types/addonConfigMerge.d.ts +17 -0
  55. package/types/addonHelper.d.ts +24 -0
  56. package/types/arrayKeysToCamel.d.ts +13 -0
  57. package/types/arrayToTree.d.ts +8 -0
  58. package/types/calcPerfTime.d.ts +4 -0
  59. package/types/configMerge.d.ts +49 -0
  60. package/types/configTypes.d.ts +26 -0
  61. package/types/defineAddonConfig.d.ts +19 -0
  62. package/types/fieldClear.d.ts +16 -0
  63. package/types/genShortId.d.ts +10 -0
  64. package/types/index.d.ts +22 -0
  65. package/types/keysToCamel.d.ts +10 -0
  66. package/types/keysToSnake.d.ts +10 -0
  67. package/types/layouts.d.ts +29 -0
  68. package/types/loadAndMergeConfig.d.ts +7 -0
  69. package/types/mergeConfig.d.ts +7 -0
  70. package/types/pickFields.d.ts +4 -0
  71. package/types/redisKeys.d.ts +34 -0
  72. package/types/regex.d.ts +143 -0
  73. package/types/scanConfig.d.ts +7 -0
  74. package/types/scanFiles.d.ts +12 -0
  75. package/types/scanViews.d.ts +11 -0
  76. package/types/types.d.ts +274 -0
@@ -0,0 +1,283 @@
1
+ /**
2
+ * befly-shared 类型定义测试
3
+ */
4
+ import { describe, expect, it } from 'bun:test';
5
+
6
+ import { ApiCode, ErrorMessages, type DatabaseConfig, type FieldDefinition, type HttpMethod, type MenuItem, type PaginatedResult, type RedisConfig, type ResponseResult, type RoleInfo, type UserInfo, type ValidationResult } from '../src/types.js';
7
+
8
+ describe('befly-shared 类型定义', () => {
9
+ describe('ResponseResult 类型', () => {
10
+ it('成功响应结构正确', () => {
11
+ const result: ResponseResult<{ id: number }> = {
12
+ code: 0,
13
+ msg: '操作成功',
14
+ data: { id: 1 }
15
+ };
16
+ expect(result.code).toBe(0);
17
+ expect(result.msg).toBe('操作成功');
18
+ expect(result.data).toEqual({ id: 1 });
19
+ });
20
+
21
+ it('失败响应结构正确', () => {
22
+ const result: ResponseResult = {
23
+ code: 1,
24
+ msg: '操作失败',
25
+ error: 'Invalid input'
26
+ };
27
+ expect(result.code).toBe(1);
28
+ expect(result.error).toBe('Invalid input');
29
+ });
30
+ });
31
+
32
+ describe('PaginatedResult 类型', () => {
33
+ it('分页结果结构正确', () => {
34
+ const result: PaginatedResult<{ name: string }> = {
35
+ code: 0,
36
+ msg: '查询成功',
37
+ data: [{ name: 'test' }],
38
+ total: 100,
39
+ page: 1,
40
+ limit: 10,
41
+ pages: 10
42
+ };
43
+ expect(result.total).toBe(100);
44
+ expect(result.pages).toBe(10);
45
+ expect(result.data).toHaveLength(1);
46
+ });
47
+ });
48
+
49
+ describe('ValidationResult 类型', () => {
50
+ it('验证成功结构正确', () => {
51
+ const result: ValidationResult = {
52
+ code: 0,
53
+ fields: {}
54
+ };
55
+ expect(result.code).toBe(0);
56
+ });
57
+
58
+ it('验证失败结构正确', () => {
59
+ const result: ValidationResult = {
60
+ code: 1,
61
+ fields: {
62
+ email: '邮箱格式不正确',
63
+ password: '密码长度不足'
64
+ }
65
+ };
66
+ expect(result.code).toBe(1);
67
+ expect(Object.keys(result.fields)).toHaveLength(2);
68
+ });
69
+ });
70
+
71
+ describe('HttpMethod 类型', () => {
72
+ it('支持所有 HTTP 方法', () => {
73
+ const methods: HttpMethod[] = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
74
+ expect(methods).toHaveLength(7);
75
+ });
76
+ });
77
+
78
+ describe('FieldDefinition 类型', () => {
79
+ it('字段定义结构正确', () => {
80
+ const field: FieldDefinition = {
81
+ name: '用户名',
82
+ detail: '用户登录名',
83
+ type: 'string',
84
+ min: 2,
85
+ max: 50,
86
+ default: null,
87
+ index: true,
88
+ unique: true,
89
+ comment: '用户名字段',
90
+ nullable: false,
91
+ unsigned: false,
92
+ regexp: '^[a-zA-Z0-9_]+$'
93
+ };
94
+ expect(field.type).toBe('string');
95
+ expect(field.unique).toBe(true);
96
+ });
97
+ });
98
+
99
+ describe('UserInfo 类型', () => {
100
+ it('用户信息结构正确', () => {
101
+ const user: UserInfo = {
102
+ id: 1,
103
+ username: 'admin',
104
+ email: 'admin@example.com',
105
+ roleCode: 'ADMIN',
106
+ customField: 'custom value'
107
+ };
108
+ expect(user.id).toBe(1);
109
+ expect(user.customField).toBe('custom value');
110
+ });
111
+ });
112
+
113
+ describe('DatabaseConfig 类型', () => {
114
+ it('数据库配置结构正确', () => {
115
+ const config: DatabaseConfig = {
116
+ type: 'mysql',
117
+ host: 'localhost',
118
+ port: 3306,
119
+ user: 'root',
120
+ password: 'password',
121
+ database: 'befly'
122
+ };
123
+ expect(config.type).toBe('mysql');
124
+ expect(config.port).toBe(3306);
125
+ });
126
+ });
127
+
128
+ describe('RedisConfig 类型', () => {
129
+ it('Redis 配置结构正确', () => {
130
+ const config: RedisConfig = {
131
+ host: 'localhost',
132
+ port: 6379,
133
+ password: 'password',
134
+ db: 0
135
+ };
136
+ expect(config.port).toBe(6379);
137
+ });
138
+
139
+ it('Redis 配置可选字段', () => {
140
+ const config: RedisConfig = {
141
+ host: 'localhost',
142
+ port: 6379
143
+ };
144
+ expect(config.password).toBeUndefined();
145
+ expect(config.db).toBeUndefined();
146
+ });
147
+ });
148
+
149
+ describe('MenuItem 类型', () => {
150
+ it('菜单项结构正确', () => {
151
+ const menu: MenuItem = {
152
+ id: 1,
153
+ pid: 0,
154
+ name: '系统管理',
155
+ path: '/system',
156
+ icon: 'Settings',
157
+ sort: 1,
158
+ hidden: false,
159
+ children: [
160
+ {
161
+ id: 2,
162
+ pid: 1,
163
+ name: '用户管理',
164
+ path: '/system/user',
165
+ sort: 1
166
+ }
167
+ ]
168
+ };
169
+ expect(menu.children).toHaveLength(1);
170
+ expect(menu.children![0].pid).toBe(1);
171
+ });
172
+ });
173
+
174
+ describe('RoleInfo 类型', () => {
175
+ it('角色信息结构正确', () => {
176
+ const role: RoleInfo = {
177
+ id: 1,
178
+ code: 'ADMIN',
179
+ name: '管理员',
180
+ desc: '系统管理员角色'
181
+ };
182
+ expect(role.code).toBe('ADMIN');
183
+ });
184
+ });
185
+
186
+ describe('ApiCode 常量', () => {
187
+ it('SUCCESS 值为 0', () => {
188
+ expect(ApiCode.SUCCESS).toBe(0);
189
+ });
190
+
191
+ it('FAIL 值为 1', () => {
192
+ expect(ApiCode.FAIL).toBe(1);
193
+ });
194
+
195
+ it('UNAUTHORIZED 值为 401', () => {
196
+ expect(ApiCode.UNAUTHORIZED).toBe(401);
197
+ });
198
+
199
+ it('FORBIDDEN 值为 403', () => {
200
+ expect(ApiCode.FORBIDDEN).toBe(403);
201
+ });
202
+
203
+ it('NOT_FOUND 值为 404', () => {
204
+ expect(ApiCode.NOT_FOUND).toBe(404);
205
+ });
206
+
207
+ it('SERVER_ERROR 值为 500', () => {
208
+ expect(ApiCode.SERVER_ERROR).toBe(500);
209
+ });
210
+ });
211
+
212
+ describe('ErrorMessages 常量', () => {
213
+ it('UNAUTHORIZED 消息正确', () => {
214
+ expect(ErrorMessages.UNAUTHORIZED).toBe('请先登录');
215
+ });
216
+
217
+ it('FORBIDDEN 消息正确', () => {
218
+ expect(ErrorMessages.FORBIDDEN).toBe('无访问权限');
219
+ });
220
+
221
+ it('NOT_FOUND 消息正确', () => {
222
+ expect(ErrorMessages.NOT_FOUND).toBe('资源不存在');
223
+ });
224
+
225
+ it('SERVER_ERROR 消息正确', () => {
226
+ expect(ErrorMessages.SERVER_ERROR).toBe('服务器错误');
227
+ });
228
+
229
+ it('INVALID_PARAMS 消息正确', () => {
230
+ expect(ErrorMessages.INVALID_PARAMS).toBe('参数错误');
231
+ });
232
+
233
+ it('TOKEN_EXPIRED 消息正确', () => {
234
+ expect(ErrorMessages.TOKEN_EXPIRED).toBe('Token 已过期');
235
+ });
236
+
237
+ it('TOKEN_INVALID 消息正确', () => {
238
+ expect(ErrorMessages.TOKEN_INVALID).toBe('Token 无效');
239
+ });
240
+ });
241
+
242
+ describe('BaseRequestContext 类型', () => {
243
+ it('请求上下文基础结构正确', () => {
244
+ const { BaseRequestContext } = require('../src/types.js') as { BaseRequestContext: any };
245
+ // BaseRequestContext 是接口,只验证可以创建符合结构的对象
246
+ const ctx = {
247
+ body: { username: 'test' },
248
+ user: { id: 1 },
249
+ now: Date.now(),
250
+ ip: '127.0.0.1',
251
+ route: 'POST/api/user/login',
252
+ requestId: 'abc123'
253
+ };
254
+ expect(ctx.body.username).toBe('test');
255
+ expect(ctx.user.id).toBe(1);
256
+ expect(typeof ctx.now).toBe('number');
257
+ expect(ctx.ip).toBe('127.0.0.1');
258
+ });
259
+ });
260
+
261
+ describe('BaseApiRoute 类型', () => {
262
+ it('API 路由基础结构正确', () => {
263
+ // BaseApiRoute 是接口,只验证可以创建符合结构的对象
264
+ const route = {
265
+ name: '用户登录',
266
+ method: 'POST' as const,
267
+ auth: false,
268
+ fields: {},
269
+ required: ['username', 'password']
270
+ };
271
+ expect(route.name).toBe('用户登录');
272
+ expect(route.method).toBe('POST');
273
+ expect(route.auth).toBe(false);
274
+ });
275
+
276
+ it('API 路由最小配置', () => {
277
+ const route = {
278
+ name: '测试接口'
279
+ };
280
+ expect(route.name).toBe('测试接口');
281
+ });
282
+ });
283
+ });
@@ -0,0 +1,17 @@
1
+ import type { MergeConfigOptions } from './configTypes.js';
2
+ /**
3
+ * Addon 配置合并函数
4
+ * 自动根据调用位置的 package.json 获取 addon 名称,然后加载项目 config 目录下的同名配置文件进行合并
5
+ * @param options - 合并选项
6
+ * @returns 合并后的配置对象
7
+ * @example
8
+ * ```ts
9
+ * // 在 @befly-addon/admin 包中调用
10
+ * const config = await addonConfigMerge();
11
+ * // 自动读取:
12
+ * // 1. @befly-addon/admin/package.json 的 befly 字段
13
+ * // 2. 项目根目录/config/admin.{js,ts,json} 配置文件
14
+ * // 3. 合并后返回
15
+ * ```
16
+ */
17
+ export declare function addonConfigMerge(options?: MergeConfigOptions): Promise<Record<string, any>>;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * 扫描所有可用的 addon
3
+ * 优先从本地 addons/ 目录加载,其次从 node_modules/@befly-addon/ 加载
4
+ * @param cwd - 项目根目录,默认为 process.cwd()
5
+ * @returns addon 名称数组
6
+ */
7
+ export declare const scanAddons: (cwd?: string) => string[];
8
+ /**
9
+ * 获取 addon 的指定子目录路径
10
+ * 优先返回本地 addons 目录,其次返回 node_modules 目录
11
+ * @param name - addon 名称
12
+ * @param subDir - 子目录名称
13
+ * @param cwd - 项目根目录,默认为 process.cwd()
14
+ * @returns 完整路径
15
+ */
16
+ export declare const getAddonDir: (name: string, subDir: string, cwd?: string) => string;
17
+ /**
18
+ * 检查 addon 子目录是否存在
19
+ * @param name - addon 名称
20
+ * @param subDir - 子目录名称
21
+ * @param cwd - 项目根目录,默认为 process.cwd()
22
+ * @returns 是否存在
23
+ */
24
+ export declare const addonDirExists: (name: string, subDir: string, cwd?: string) => boolean;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 数组对象字段名批量转小驼峰
3
+ * @param arr - 源数组
4
+ * @returns 字段名转为小驼峰格式的新数组
5
+ *
6
+ * @example
7
+ * arrayKeysToCamel([
8
+ * { user_id: 1, user_name: 'John' },
9
+ * { user_id: 2, user_name: 'Jane' }
10
+ * ])
11
+ * // [{ userId: 1, userName: 'John' }, { userId: 2, userName: 'Jane' }]
12
+ */
13
+ export declare const arrayKeysToCamel: <T = any>(arr: Record<string, any>[]) => T[];
@@ -0,0 +1,8 @@
1
+ export interface ArrayToTreeOptions<T = any> {
2
+ idField?: string;
3
+ pidField?: string;
4
+ childrenField?: string;
5
+ rootPid?: any;
6
+ mapFn?: (node: T) => T;
7
+ }
8
+ export declare function arrayToTree<T = any>(items: T[], options?: ArrayToTreeOptions<T>): T[];
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 计算性能时间差
3
+ */
4
+ export declare const calcPerfTime: (startTime: number, endTime?: number) => string;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 配置来源信息
3
+ */
4
+ export interface ConfigSource {
5
+ /** 配置文件路径 */
6
+ filePath: string;
7
+ /** 配置数据 */
8
+ data: Record<string, any>;
9
+ }
10
+ /**
11
+ * 合并配置选项
12
+ */
13
+ export interface MergeConfigOptions {
14
+ /** 合并策略:deep 深度合并(默认),shallow 浅合并,override 覆盖 */
15
+ strategy?: 'deep' | 'shallow' | 'override';
16
+ /** 是否克隆数据(避免引用污染),默认 true */
17
+ clone?: boolean;
18
+ }
19
+ /**
20
+ * 加载配置选项
21
+ */
22
+ export interface LoadConfigOptions {
23
+ /** 目录数组:要搜索的目录路径 */
24
+ dirs: string[];
25
+ /** 文件数组:要匹配的文件名 */
26
+ files: string[];
27
+ /** 合并选项 */
28
+ merge?: MergeConfigOptions;
29
+ /** 是否必须找到至少一个配置文件,默认 false */
30
+ required?: boolean;
31
+ /** 文件扩展名,默认 ['.js', '.ts', '.json'] */
32
+ extensions?: string[];
33
+ }
34
+ /**
35
+ * 合并多个配置对象
36
+ * @param configs - 配置对象数组
37
+ * @param options - 合并选项
38
+ * @returns 合并后的配置对象
39
+ */
40
+ export declare function mergeConfig(configs: Record<string, any>[], options?: MergeConfigOptions): Record<string, any>;
41
+ /**
42
+ * 加载并合并配置文件(矩阵搜索:dirs × files)
43
+ * @param options - 加载选项
44
+ * @returns 合并后的配置对象和来源信息
45
+ */
46
+ export declare function loadAndMergeConfig(options: LoadConfigOptions): Promise<{
47
+ config: Record<string, any>;
48
+ sources: ConfigSource[];
49
+ }>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * 加载配置选项
3
+ */
4
+ export interface LoadConfigOptions {
5
+ /** 当前工作目录,默认 process.cwd() */
6
+ cwd?: string;
7
+ /** 目录数组:要搜索的目录路径(相对于 cwd) */
8
+ dirs: string[];
9
+ /** 文件数组:要匹配的文件名 */
10
+ files: string[];
11
+ /** 文件扩展名,默认 ['.js', '.ts', '.json'] */
12
+ extensions?: string[];
13
+ /** 加载模式:'first' = 返回第一个找到的配置(默认),'all' = 合并所有配置 */
14
+ mode?: 'all' | 'first';
15
+ /** 指定要提取的字段路径数组,如 ['menus', 'database.host'],为空则返回完整对象 */
16
+ paths?: string[];
17
+ }
18
+ /**
19
+ * Addon 配置合并选项(已废弃,仅用于向后兼容)
20
+ */
21
+ export interface MergeConfigOptions {
22
+ /** 合并策略(已废弃,始终使用 deep) */
23
+ strategy?: 'deep' | 'shallow' | 'override';
24
+ /** 是否克隆数据(已废弃) */
25
+ clone?: boolean;
26
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Addon 配置定义函数
3
+ * 接受 addon 配置对象,从当前执行目录的 config 目录下查找同名配置文件进行合并
4
+ * 只能在 addon.config.js 文件中使用
5
+ * @param metaDirname - import.meta.dirname
6
+ * @param addonConfig - addon 配置对象
7
+ * @returns 合并后的配置对象
8
+ * @example
9
+ * ```ts
10
+ * // 在 packages/addonAdmin/addon.config.js 中
11
+ * import { defineAddonConfig } from 'befly-shared/defineAddonConfig';
12
+ *
13
+ * export default defineAddonConfig(import.meta.dirname, {
14
+ * menus: [...]
15
+ * });
16
+ * // 自动从目录名提取 addon 名称,并从 process.cwd()/config/addonAdmin.{js,ts,json} 读取配置并合并
17
+ * ```
18
+ */
19
+ export declare function defineAddonConfig(metaDirname: string, addonConfig?: Record<string, any>): Promise<Record<string, any>>;
@@ -0,0 +1,16 @@
1
+ export interface FieldClearOptions {
2
+ pickKeys?: string[];
3
+ omitKeys?: string[];
4
+ keepValues?: any[];
5
+ excludeValues?: any[];
6
+ keepMap?: Record<string, any>;
7
+ }
8
+ export type FieldClearResult<T> =
9
+ T extends Array<infer U>
10
+ ? Array<FieldClearResult<U>>
11
+ : T extends object
12
+ ? {
13
+ [K in keyof T]?: T[K];
14
+ }
15
+ : T;
16
+ export declare function fieldClear<T = any>(data: T | T[], options?: FieldClearOptions): FieldClearResult<T>;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 生成短 ID
3
+ * 由时间戳(base36)+ 随机字符组成,约 13 位
4
+ * - 前 8 位:时间戳(可排序)
5
+ * - 后 5 位:随机字符(防冲突)
6
+ * @returns 短 ID 字符串
7
+ * @example
8
+ * genShortId() // "lxyz1a2b3c4"
9
+ */
10
+ export declare function genShortId(): string;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Befly Shared 统一导出
3
+ * 跨包共享的工具函数、常量、类型定义
4
+ */
5
+ export * from './types.js';
6
+ export * from './redisKeys.js';
7
+ export * from './regex.js';
8
+ export * from './defineAddonConfig.js';
9
+ export * from './addonHelper.js';
10
+ export * from './arrayKeysToCamel.js';
11
+ export * from './arrayToTree.js';
12
+ export * from './calcPerfTime.js';
13
+ export * from './configTypes.js';
14
+ export * from './genShortId.js';
15
+ export * from './scanConfig.js';
16
+ export * from './fieldClear.js';
17
+ export * from './keysToCamel.js';
18
+ export * from './keysToSnake.js';
19
+ export * from './layouts.js';
20
+ export * from './pickFields.js';
21
+ export * from './scanFiles.js';
22
+ export * from './scanViews.js';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 对象字段名转小驼峰
3
+ * @param obj - 源对象
4
+ * @returns 字段名转为小驼峰格式的新对象
5
+ *
6
+ * @example
7
+ * keysToCamel({ user_id: 123, user_name: 'John' }) // { userId: 123, userName: 'John' }
8
+ * keysToCamel({ created_at: 1697452800000 }) // { createdAt: 1697452800000 }
9
+ */
10
+ export declare const keysToCamel: <T = any>(obj: Record<string, any>) => T;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 对象字段名转下划线
3
+ * @param obj - 源对象
4
+ * @returns 字段名转为下划线格式的新对象
5
+ *
6
+ * @example
7
+ * keysToSnake({ userId: 123, userName: 'John' }) // { user_id: 123, user_name: 'John' }
8
+ * keysToSnake({ createdAt: 1697452800000 }) // { created_at: 1697452800000 }
9
+ */
10
+ export declare const keysToSnake: <T = any>(obj: Record<string, any>) => T;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * 路由配置接口
3
+ */
4
+ export interface RouteConfig {
5
+ path?: string;
6
+ component?: any;
7
+ children?: RouteConfig[];
8
+ meta?: Record<string, any>;
9
+ [key: string]: any;
10
+ }
11
+ /**
12
+ * 布局配置接口
13
+ */
14
+ export interface LayoutConfig {
15
+ path: string;
16
+ layoutName: string;
17
+ component: any;
18
+ children?: LayoutConfig[];
19
+ meta?: Record<string, any>;
20
+ [key: string]: any;
21
+ }
22
+ /**
23
+ * 自定义布局处理函数
24
+ * 根据文件名后缀判断使用哪个布局
25
+ * @param routes - 原始路由配置
26
+ * @param inheritLayout - 继承的布局名称(来自父级目录)
27
+ * @returns 处理后的布局配置(不包含实际的布局组件导入)
28
+ */
29
+ export declare function Layouts(routes: RouteConfig[], inheritLayout?: string): LayoutConfig[];
@@ -0,0 +1,7 @@
1
+ import type { LoadConfigOptions } from './configTypes.js';
2
+ /**
3
+ * 加载并合并配置文件(矩阵搜索:dirs × files)
4
+ * @param options - 加载选项
5
+ * @returns 合并后的配置对象
6
+ */
7
+ export declare function loadAndMergeConfig(options: LoadConfigOptions): Promise<Record<string, any>>;
@@ -0,0 +1,7 @@
1
+ import type { LoadConfigOptions } from './configTypes.js';
2
+ /**
3
+ * 加载并合并配置文件(矩阵搜索:dirs × files)
4
+ * @param options - 加载选项
5
+ * @returns 合并后的配置对象
6
+ */
7
+ export declare function mergeConfig(options: LoadConfigOptions): Promise<Record<string, any>>;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * 挑选指定字段
3
+ */
4
+ export declare const pickFields: <T extends Record<string, any>>(obj: T, keys: string[]) => Partial<T>;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Redis Key 统一管理
3
+ * 所有 Redis 缓存键在此统一定义,避免硬编码分散
4
+ */
5
+ /**
6
+ * Redis Key 生成函数集合
7
+ */
8
+ export declare const RedisKeys: {
9
+ /** 所有接口缓存 */
10
+ readonly apisAll: () => string;
11
+ /** 所有菜单缓存 */
12
+ readonly menusAll: () => string;
13
+ /** 角色信息缓存(完整角色对象) */
14
+ readonly roleInfo: (roleCode: string) => string;
15
+ /** 角色接口权限缓存(Set 集合) */
16
+ readonly roleApis: (roleCode: string) => string;
17
+ /** 表结构缓存 */
18
+ readonly tableColumns: (table: string) => string;
19
+ };
20
+ /**
21
+ * Redis TTL(过期时间)常量配置(单位:秒)
22
+ */
23
+ export declare const RedisTTL: {
24
+ /** 表结构缓存 - 1小时 */
25
+ readonly tableColumns: 3600;
26
+ /** 角色接口权限 - 24小时 */
27
+ readonly roleApis: 86400;
28
+ /** 角色信息 - 24小时 */
29
+ readonly roleInfo: 86400;
30
+ /** 接口列表 - 永久(不过期) */
31
+ readonly apisAll: null;
32
+ /** 菜单列表 - 永久(不过期) */
33
+ readonly menusAll: null;
34
+ };