befly 3.16.9 → 3.16.11

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 (178) hide show
  1. package/README.md +0 -129
  2. package/befly.js +12769 -0
  3. package/befly.min.js +47 -0
  4. package/package.json +18 -29
  5. package/dist/befly.config.d.ts +0 -7
  6. package/dist/befly.config.js +0 -128
  7. package/dist/befly.js +0 -17276
  8. package/dist/befly.min.js +0 -23
  9. package/dist/checks/checkApi.d.ts +0 -1
  10. package/dist/checks/checkApi.js +0 -124
  11. package/dist/checks/checkConfig.d.ts +0 -9
  12. package/dist/checks/checkConfig.js +0 -255
  13. package/dist/checks/checkHook.d.ts +0 -1
  14. package/dist/checks/checkHook.js +0 -132
  15. package/dist/checks/checkMenu.d.ts +0 -3
  16. package/dist/checks/checkMenu.js +0 -106
  17. package/dist/checks/checkPlugin.d.ts +0 -1
  18. package/dist/checks/checkPlugin.js +0 -132
  19. package/dist/checks/checkTable.d.ts +0 -7
  20. package/dist/checks/checkTable.js +0 -431
  21. package/dist/configs/presetRegexp.d.ts +0 -145
  22. package/dist/configs/presetRegexp.js +0 -218
  23. package/dist/hooks/auth.d.ts +0 -3
  24. package/dist/hooks/auth.js +0 -24
  25. package/dist/hooks/cors.d.ts +0 -7
  26. package/dist/hooks/cors.js +0 -36
  27. package/dist/hooks/parser.d.ts +0 -10
  28. package/dist/hooks/parser.js +0 -76
  29. package/dist/hooks/permission.d.ts +0 -10
  30. package/dist/hooks/permission.js +0 -64
  31. package/dist/hooks/validator.d.ts +0 -7
  32. package/dist/hooks/validator.js +0 -52
  33. package/dist/index.d.ts +0 -28
  34. package/dist/index.js +0 -316
  35. package/dist/lib/asyncContext.d.ts +0 -21
  36. package/dist/lib/asyncContext.js +0 -27
  37. package/dist/lib/cacheHelper.d.ts +0 -128
  38. package/dist/lib/cacheHelper.js +0 -477
  39. package/dist/lib/cacheKeys.d.ts +0 -27
  40. package/dist/lib/cacheKeys.js +0 -37
  41. package/dist/lib/cipher.d.ts +0 -153
  42. package/dist/lib/cipher.js +0 -237
  43. package/dist/lib/connect.d.ts +0 -95
  44. package/dist/lib/connect.js +0 -313
  45. package/dist/lib/dbHelper.d.ts +0 -229
  46. package/dist/lib/dbHelper.js +0 -1069
  47. package/dist/lib/dbUtils.d.ts +0 -91
  48. package/dist/lib/dbUtils.js +0 -544
  49. package/dist/lib/jwt.d.ts +0 -13
  50. package/dist/lib/jwt.js +0 -77
  51. package/dist/lib/logger.d.ts +0 -46
  52. package/dist/lib/logger.js +0 -731
  53. package/dist/lib/redisHelper.d.ts +0 -193
  54. package/dist/lib/redisHelper.js +0 -598
  55. package/dist/lib/sqlBuilder.d.ts +0 -160
  56. package/dist/lib/sqlBuilder.js +0 -837
  57. package/dist/lib/sqlCheck.d.ts +0 -23
  58. package/dist/lib/sqlCheck.js +0 -119
  59. package/dist/lib/validator.d.ts +0 -45
  60. package/dist/lib/validator.js +0 -424
  61. package/dist/loader/loadApis.d.ts +0 -12
  62. package/dist/loader/loadApis.js +0 -71
  63. package/dist/loader/loadHooks.d.ts +0 -7
  64. package/dist/loader/loadHooks.js +0 -50
  65. package/dist/loader/loadPlugins.d.ts +0 -8
  66. package/dist/loader/loadPlugins.js +0 -69
  67. package/dist/paths.d.ts +0 -93
  68. package/dist/paths.js +0 -100
  69. package/dist/plugins/cache.d.ts +0 -10
  70. package/dist/plugins/cache.js +0 -24
  71. package/dist/plugins/cipher.d.ts +0 -7
  72. package/dist/plugins/cipher.js +0 -14
  73. package/dist/plugins/config.d.ts +0 -3
  74. package/dist/plugins/config.js +0 -9
  75. package/dist/plugins/db.d.ts +0 -10
  76. package/dist/plugins/db.js +0 -48
  77. package/dist/plugins/jwt.d.ts +0 -6
  78. package/dist/plugins/jwt.js +0 -13
  79. package/dist/plugins/logger.d.ts +0 -10
  80. package/dist/plugins/logger.js +0 -21
  81. package/dist/plugins/redis.d.ts +0 -10
  82. package/dist/plugins/redis.js +0 -40
  83. package/dist/plugins/tool.d.ts +0 -75
  84. package/dist/plugins/tool.js +0 -105
  85. package/dist/router/api.d.ts +0 -14
  86. package/dist/router/api.js +0 -109
  87. package/dist/router/static.d.ts +0 -9
  88. package/dist/router/static.js +0 -56
  89. package/dist/scripts/ensureDist.d.ts +0 -1
  90. package/dist/scripts/ensureDist.js +0 -296
  91. package/dist/sync/syncApi.d.ts +0 -3
  92. package/dist/sync/syncApi.js +0 -140
  93. package/dist/sync/syncCache.d.ts +0 -2
  94. package/dist/sync/syncCache.js +0 -14
  95. package/dist/sync/syncDev.d.ts +0 -6
  96. package/dist/sync/syncDev.js +0 -166
  97. package/dist/sync/syncMenu.d.ts +0 -14
  98. package/dist/sync/syncMenu.js +0 -308
  99. package/dist/sync/syncTable.d.ts +0 -126
  100. package/dist/sync/syncTable.js +0 -1129
  101. package/dist/types/api.d.ts +0 -175
  102. package/dist/types/api.js +0 -4
  103. package/dist/types/befly.d.ts +0 -231
  104. package/dist/types/befly.js +0 -4
  105. package/dist/types/cache.d.ts +0 -96
  106. package/dist/types/cache.js +0 -4
  107. package/dist/types/cipher.d.ts +0 -27
  108. package/dist/types/cipher.js +0 -7
  109. package/dist/types/common.d.ts +0 -127
  110. package/dist/types/common.js +0 -5
  111. package/dist/types/context.d.ts +0 -39
  112. package/dist/types/context.js +0 -4
  113. package/dist/types/coreError.d.ts +0 -31
  114. package/dist/types/coreError.js +0 -38
  115. package/dist/types/crypto.d.ts +0 -20
  116. package/dist/types/crypto.js +0 -4
  117. package/dist/types/database.d.ts +0 -182
  118. package/dist/types/database.js +0 -4
  119. package/dist/types/hook.d.ts +0 -30
  120. package/dist/types/hook.js +0 -19
  121. package/dist/types/jwt.d.ts +0 -76
  122. package/dist/types/jwt.js +0 -4
  123. package/dist/types/logger.d.ts +0 -95
  124. package/dist/types/logger.js +0 -6
  125. package/dist/types/plugin.d.ts +0 -27
  126. package/dist/types/plugin.js +0 -17
  127. package/dist/types/redis.d.ts +0 -80
  128. package/dist/types/redis.js +0 -4
  129. package/dist/types/roleApisCache.d.ts +0 -21
  130. package/dist/types/roleApisCache.js +0 -8
  131. package/dist/types/sync.d.ts +0 -93
  132. package/dist/types/sync.js +0 -4
  133. package/dist/types/table.d.ts +0 -34
  134. package/dist/types/table.js +0 -4
  135. package/dist/types/validate.d.ts +0 -113
  136. package/dist/types/validate.js +0 -4
  137. package/dist/utils/calcPerfTime.d.ts +0 -4
  138. package/dist/utils/calcPerfTime.js +0 -13
  139. package/dist/utils/cors.d.ts +0 -8
  140. package/dist/utils/cors.js +0 -17
  141. package/dist/utils/dbFieldRules.d.ts +0 -31
  142. package/dist/utils/dbFieldRules.js +0 -94
  143. package/dist/utils/fieldClear.d.ts +0 -11
  144. package/dist/utils/fieldClear.js +0 -57
  145. package/dist/utils/formatYmdHms.d.ts +0 -1
  146. package/dist/utils/formatYmdHms.js +0 -20
  147. package/dist/utils/getClientIp.d.ts +0 -6
  148. package/dist/utils/getClientIp.js +0 -39
  149. package/dist/utils/importDefault.d.ts +0 -1
  150. package/dist/utils/importDefault.js +0 -53
  151. package/dist/utils/isDirentDirectory.d.ts +0 -3
  152. package/dist/utils/isDirentDirectory.js +0 -18
  153. package/dist/utils/loadMenuConfigs.d.ts +0 -11
  154. package/dist/utils/loadMenuConfigs.js +0 -130
  155. package/dist/utils/loggerUtils.d.ts +0 -18
  156. package/dist/utils/loggerUtils.js +0 -171
  157. package/dist/utils/mergeAndConcat.d.ts +0 -7
  158. package/dist/utils/mergeAndConcat.js +0 -77
  159. package/dist/utils/normalizeFieldDefinition.d.ts +0 -18
  160. package/dist/utils/normalizeFieldDefinition.js +0 -27
  161. package/dist/utils/processInfo.d.ts +0 -26
  162. package/dist/utils/processInfo.js +0 -41
  163. package/dist/utils/response.d.ts +0 -20
  164. package/dist/utils/response.js +0 -96
  165. package/dist/utils/scanAddons.d.ts +0 -15
  166. package/dist/utils/scanAddons.js +0 -35
  167. package/dist/utils/scanCoreBuiltins.d.ts +0 -3
  168. package/dist/utils/scanCoreBuiltins.js +0 -72
  169. package/dist/utils/scanFiles.d.ts +0 -32
  170. package/dist/utils/scanFiles.js +0 -124
  171. package/dist/utils/scanSources.d.ts +0 -10
  172. package/dist/utils/scanSources.js +0 -46
  173. package/dist/utils/sortModules.d.ts +0 -28
  174. package/dist/utils/sortModules.js +0 -105
  175. package/dist/utils/sqlUtil.d.ts +0 -33
  176. package/dist/utils/sqlUtil.js +0 -146
  177. package/dist/utils/util.d.ts +0 -172
  178. package/dist/utils/util.js +0 -517
@@ -1,145 +0,0 @@
1
- /**
2
- * 内置正则表达式别名
3
- * 用于表单验证和数据校验
4
- * 命名规范:小驼峰格式
5
- */
6
- export declare const RegexAliases: {
7
- /** 正整数(不含0) */
8
- readonly number: "^\\d+$";
9
- /** 整数(含负数) */
10
- readonly integer: "^-?\\d+$";
11
- /** 浮点数 */
12
- readonly float: "^-?\\d+(\\.\\d+)?$";
13
- /** 正整数(不含0) */
14
- readonly positive: "^[1-9]\\d*$";
15
- /** 负整数 */
16
- readonly negative: "^-\\d+$";
17
- /** 零 */
18
- readonly zero: "^0$";
19
- /** 纯字母 */
20
- readonly word: "^[a-zA-Z]+$";
21
- /** 字母和数字 */
22
- readonly alphanumeric: "^[a-zA-Z0-9]+$";
23
- /** 字母、数字和下划线 */
24
- readonly alphanumeric_: "^[a-zA-Z0-9_]+$";
25
- /** 字母、数字、下划线和短横线 */
26
- readonly alphanumericDash_: "^[a-zA-Z0-9_-]+$";
27
- /** 小写字母 */
28
- readonly lowercase: "^[a-z]+$";
29
- /** 大写字母 */
30
- readonly uppercase: "^[A-Z]+$";
31
- /** 纯中文 */
32
- readonly chinese: "^[\\u4e00-\\u9fa5]+$";
33
- /** 中文和字母 */
34
- readonly chineseWord: "^[\\u4e00-\\u9fa5a-zA-Z]+$";
35
- /** 邮箱地址 */
36
- readonly email: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$";
37
- /** 中国大陆手机号 */
38
- readonly phone: "^1[3-9]\\d{9}$";
39
- /** 固定电话(区号-号码) */
40
- readonly telephone: "^0\\d{2,3}-?\\d{7,8}$";
41
- /** URL 地址 */
42
- readonly url: "^https?://";
43
- /** IPv4 地址 */
44
- readonly ip: "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
45
- /** IPv6 地址 */
46
- readonly ipv6: "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$";
47
- /** 域名 */
48
- readonly domain: "^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$";
49
- /** UUID */
50
- readonly uuid: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$";
51
- /** 十六进制字符串 */
52
- readonly hex: "^[0-9a-fA-F]+$";
53
- /** Base64 编码 */
54
- readonly base64: "^[A-Za-z0-9+/=]+$";
55
- /** MD5 哈希 */
56
- readonly md5: "^[a-f0-9]{32}$";
57
- /** SHA1 哈希 */
58
- readonly sha1: "^[a-f0-9]{40}$";
59
- /** SHA256 哈希 */
60
- readonly sha256: "^[a-f0-9]{64}$";
61
- /** 日期 YYYY-MM-DD */
62
- readonly date: "^\\d{4}-\\d{2}-\\d{2}$";
63
- /** 时间 HH:MM:SS */
64
- readonly time: "^\\d{2}:\\d{2}:\\d{2}$";
65
- /** ISO 日期时间 */
66
- readonly datetime: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}";
67
- /** 年份 */
68
- readonly year: "^\\d{4}$";
69
- /** 月份 01-12 */
70
- readonly month: "^(0[1-9]|1[0-2])$";
71
- /** 日期 01-31 */
72
- readonly day: "^(0[1-9]|[12]\\d|3[01])$";
73
- /** 变量名 */
74
- readonly variable: "^[a-zA-Z_][a-zA-Z0-9_]*$";
75
- /** 常量名(全大写) */
76
- readonly constant: "^[A-Z][A-Z0-9_]*$";
77
- /** 包名(小写+连字符) */
78
- readonly package: "^[a-z][a-z0-9-]*$";
79
- /** 中国身份证号(18位) */
80
- readonly idCard: "^\\d{17}[\\dXx]$";
81
- /** 护照号 */
82
- readonly passport: "^[a-zA-Z0-9]{5,17}$";
83
- /** 银行卡号(16-19位数字) */
84
- readonly bankCard: "^\\d{16,19}$";
85
- /** 微信号(6-20位,字母开头,可包含字母、数字、下划线、减号) */
86
- readonly wechat: "^[a-zA-Z][a-zA-Z0-9_-]{5,19}$";
87
- /** QQ号(5-11位数字,首位非0) */
88
- readonly qq: "^[1-9]\\d{4,10}$";
89
- /** 支付宝账号(手机号或邮箱) */
90
- readonly alipay: "^(1[3-9]\\d{9}|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$";
91
- /** 用户名(4-20位,字母开头,可包含字母、数字、下划线) */
92
- readonly username: "^[a-zA-Z][a-zA-Z0-9_]{3,19}$";
93
- /** 昵称(2-20位,支持中文、字母、数字) */
94
- readonly nickname: "^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$";
95
- /** 弱密码(至少6位) */
96
- readonly passwordWeak: "^.{6,}$";
97
- /** 中等密码(至少8位,包含字母和数字) */
98
- readonly passwordMedium: "^(?=.*[a-zA-Z])(?=.*\\d).{8,}$";
99
- /** 强密码(至少8位,包含大小写字母、数字和特殊字符) */
100
- readonly passwordStrong: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$";
101
- /** 车牌号(新能源+普通) */
102
- readonly licensePlate: "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$";
103
- /** 邮政编码 */
104
- readonly postalCode: "^\\d{6}$";
105
- /** 版本号(语义化版本) */
106
- readonly semver: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$";
107
- /** 颜色值(十六进制) */
108
- readonly colorHex: "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$";
109
- /** 空字符串 */
110
- readonly empty: "^$";
111
- /** 非空 */
112
- readonly notempty: ".+";
113
- };
114
- /**
115
- * 正则别名类型
116
- */
117
- export type RegexAliasName = keyof typeof RegexAliases;
118
- /**
119
- * 获取正则表达式字符串
120
- * @param name 正则别名(以 @ 开头)或自定义正则字符串
121
- * @returns 正则表达式字符串
122
- */
123
- export declare function getRegex(name: string): string;
124
- /**
125
- * 获取编译后的正则表达式对象(带缓存)
126
- * @param pattern 正则别名或正则字符串
127
- * @param flags 正则标志(如 'i', 'g')
128
- * @returns 编译后的 RegExp 对象
129
- */
130
- export declare function getCompiledRegex(pattern: string, flags?: string): RegExp;
131
- /**
132
- * 验证值是否匹配正则(使用缓存)
133
- * @param value 要验证的值
134
- * @param pattern 正则别名或正则字符串
135
- * @returns 是否匹配
136
- */
137
- export declare function matchRegex(value: string, pattern: string): boolean;
138
- /**
139
- * 清除正则缓存
140
- */
141
- export declare function clearRegexCache(): void;
142
- /**
143
- * 获取缓存大小
144
- */
145
- export declare function getRegexCacheSize(): number;
@@ -1,218 +0,0 @@
1
- /**
2
- * 内置正则表达式别名
3
- * 用于表单验证和数据校验
4
- * 命名规范:小驼峰格式
5
- */
6
- export const RegexAliases = {
7
- // ============================================
8
- // 数字类型
9
- // ============================================
10
- /** 正整数(不含0) */
11
- number: "^\\d+$",
12
- /** 整数(含负数) */
13
- integer: "^-?\\d+$",
14
- /** 浮点数 */
15
- float: "^-?\\d+(\\.\\d+)?$",
16
- /** 正整数(不含0) */
17
- positive: "^[1-9]\\d*$",
18
- /** 负整数 */
19
- negative: "^-\\d+$",
20
- /** 零 */
21
- zero: "^0$",
22
- // ============================================
23
- // 字符串类型
24
- // ============================================
25
- /** 纯字母 */
26
- word: "^[a-zA-Z]+$",
27
- /** 字母和数字 */
28
- alphanumeric: "^[a-zA-Z0-9]+$",
29
- /** 字母、数字和下划线 */
30
- alphanumeric_: "^[a-zA-Z0-9_]+$",
31
- /** 字母、数字、下划线和短横线 */
32
- alphanumericDash_: "^[a-zA-Z0-9_-]+$",
33
- /** 小写字母 */
34
- lowercase: "^[a-z]+$",
35
- /** 大写字母 */
36
- uppercase: "^[A-Z]+$",
37
- // ============================================
38
- // 中文
39
- // ============================================
40
- /** 纯中文 */
41
- chinese: "^[\\u4e00-\\u9fa5]+$",
42
- /** 中文和字母 */
43
- chineseWord: "^[\\u4e00-\\u9fa5a-zA-Z]+$",
44
- // ============================================
45
- // 常用格式
46
- // ============================================
47
- /** 邮箱地址 */
48
- email: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
49
- /** 中国大陆手机号 */
50
- phone: "^1[3-9]\\d{9}$",
51
- /** 固定电话(区号-号码) */
52
- telephone: "^0\\d{2,3}-?\\d{7,8}$",
53
- /** URL 地址 */
54
- url: "^https?://",
55
- /** IPv4 地址 */
56
- ip: "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$",
57
- /** IPv6 地址 */
58
- ipv6: "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",
59
- /** 域名 */
60
- domain: "^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$",
61
- // ============================================
62
- // 特殊格式
63
- // ============================================
64
- /** UUID */
65
- uuid: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
66
- /** 十六进制字符串 */
67
- hex: "^[0-9a-fA-F]+$",
68
- /** Base64 编码 */
69
- base64: "^[A-Za-z0-9+/=]+$",
70
- /** MD5 哈希 */
71
- md5: "^[a-f0-9]{32}$",
72
- /** SHA1 哈希 */
73
- sha1: "^[a-f0-9]{40}$",
74
- /** SHA256 哈希 */
75
- sha256: "^[a-f0-9]{64}$",
76
- // ============================================
77
- // 日期时间
78
- // ============================================
79
- /** 日期 YYYY-MM-DD */
80
- date: "^\\d{4}-\\d{2}-\\d{2}$",
81
- /** 时间 HH:MM:SS */
82
- time: "^\\d{2}:\\d{2}:\\d{2}$",
83
- /** ISO 日期时间 */
84
- datetime: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}",
85
- /** 年份 */
86
- year: "^\\d{4}$",
87
- /** 月份 01-12 */
88
- month: "^(0[1-9]|1[0-2])$",
89
- /** 日期 01-31 */
90
- day: "^(0[1-9]|[12]\\d|3[01])$",
91
- // ============================================
92
- // 代码相关
93
- // ============================================
94
- /** 变量名 */
95
- variable: "^[a-zA-Z_][a-zA-Z0-9_]*$",
96
- /** 常量名(全大写) */
97
- constant: "^[A-Z][A-Z0-9_]*$",
98
- /** 包名(小写+连字符) */
99
- package: "^[a-z][a-z0-9-]*$",
100
- // ============================================
101
- // 证件相关
102
- // ============================================
103
- /** 中国身份证号(18位) */
104
- idCard: "^\\d{17}[\\dXx]$",
105
- /** 护照号 */
106
- passport: "^[a-zA-Z0-9]{5,17}$",
107
- // ============================================
108
- // 账号相关(国内常用)
109
- // ============================================
110
- /** 银行卡号(16-19位数字) */
111
- bankCard: "^\\d{16,19}$",
112
- /** 微信号(6-20位,字母开头,可包含字母、数字、下划线、减号) */
113
- wechat: "^[a-zA-Z][a-zA-Z0-9_-]{5,19}$",
114
- /** QQ号(5-11位数字,首位非0) */
115
- qq: "^[1-9]\\d{4,10}$",
116
- /** 支付宝账号(手机号或邮箱) */
117
- alipay: "^(1[3-9]\\d{9}|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$",
118
- /** 用户名(4-20位,字母开头,可包含字母、数字、下划线) */
119
- username: "^[a-zA-Z][a-zA-Z0-9_]{3,19}$",
120
- /** 昵称(2-20位,支持中文、字母、数字) */
121
- nickname: "^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$",
122
- // ============================================
123
- // 密码强度
124
- // ============================================
125
- /** 弱密码(至少6位) */
126
- passwordWeak: "^.{6,}$",
127
- /** 中等密码(至少8位,包含字母和数字) */
128
- passwordMedium: "^(?=.*[a-zA-Z])(?=.*\\d).{8,}$",
129
- /** 强密码(至少8位,包含大小写字母、数字和特殊字符) */
130
- passwordStrong: "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$",
131
- // ============================================
132
- // 其他常用
133
- // ============================================
134
- /** 车牌号(新能源+普通) */
135
- licensePlate: "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$",
136
- /** 邮政编码 */
137
- postalCode: "^\\d{6}$",
138
- /** 版本号(语义化版本) */
139
- semver: "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$",
140
- /** 颜色值(十六进制) */
141
- colorHex: "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$",
142
- // ============================================
143
- // 空值
144
- // ============================================
145
- /** 空字符串 */
146
- empty: "^$",
147
- /** 非空 */
148
- notempty: ".+"
149
- };
150
- // ============================================
151
- // 正则表达式缓存(性能优化)
152
- // ============================================
153
- const regexCache = new Map();
154
- /**
155
- * 获取正则表达式字符串
156
- * @param name 正则别名(以 @ 开头)或自定义正则字符串
157
- * @returns 正则表达式字符串
158
- */
159
- export function getRegex(name) {
160
- if (name.startsWith("@")) {
161
- const alias = name.slice(1);
162
- return RegexAliases[alias] || name;
163
- }
164
- return name;
165
- }
166
- function parseRegexLiteral(pattern) {
167
- const trimmed = String(pattern || "").trim();
168
- if (trimmed.length < 2)
169
- return null;
170
- if (!trimmed.startsWith("/"))
171
- return null;
172
- const lastSlash = trimmed.lastIndexOf("/");
173
- if (lastSlash <= 0)
174
- return null;
175
- const flags = trimmed.slice(lastSlash + 1);
176
- if (flags !== "" && !/^[gimsuy]+$/.test(flags))
177
- return null;
178
- return { source: trimmed.slice(1, lastSlash), flags: flags };
179
- }
180
- /**
181
- * 获取编译后的正则表达式对象(带缓存)
182
- * @param pattern 正则别名或正则字符串
183
- * @param flags 正则标志(如 'i', 'g')
184
- * @returns 编译后的 RegExp 对象
185
- */
186
- export function getCompiledRegex(pattern, flags) {
187
- const literal = parseRegexLiteral(pattern);
188
- const regexStr = literal ? literal.source : getRegex(pattern);
189
- const useFlags = literal && literal.flags !== "" ? literal.flags : flags || "";
190
- const cacheKey = `${regexStr}:${useFlags}`;
191
- let cached = regexCache.get(cacheKey);
192
- if (!cached) {
193
- cached = new RegExp(regexStr, useFlags);
194
- regexCache.set(cacheKey, cached);
195
- }
196
- return cached;
197
- }
198
- /**
199
- * 验证值是否匹配正则(使用缓存)
200
- * @param value 要验证的值
201
- * @param pattern 正则别名或正则字符串
202
- * @returns 是否匹配
203
- */
204
- export function matchRegex(value, pattern) {
205
- return getCompiledRegex(pattern).test(value);
206
- }
207
- /**
208
- * 清除正则缓存
209
- */
210
- export function clearRegexCache() {
211
- regexCache.clear();
212
- }
213
- /**
214
- * 获取缓存大小
215
- */
216
- export function getRegexCacheSize() {
217
- return regexCache.size;
218
- }
@@ -1,3 +0,0 @@
1
- import type { Hook } from "../types/hook";
2
- declare const authHook: Hook;
3
- export default authHook;
@@ -1,24 +0,0 @@
1
- import { setCtxUser } from "../lib/asyncContext";
2
- const authHook = {
3
- name: "auth",
4
- enable: true,
5
- deps: ["cors"],
6
- handler: async (befly, ctx) => {
7
- const authHeader = ctx.req.headers.get("authorization");
8
- if (authHeader && authHeader.startsWith("Bearer ")) {
9
- const token = authHeader.substring(7);
10
- try {
11
- const payload = await befly.jwt.verify(token);
12
- ctx.user = payload;
13
- setCtxUser(payload.id, payload.roleCode, payload.nickname, payload.roleType);
14
- }
15
- catch {
16
- ctx.user = {};
17
- }
18
- }
19
- else {
20
- ctx.user = {};
21
- }
22
- }
23
- };
24
- export default authHook;
@@ -1,7 +0,0 @@
1
- import type { Hook } from "../types/hook";
2
- /**
3
- * CORS 跨域处理钩子
4
- * 设置跨域响应头并处理 OPTIONS 预检请求
5
- */
6
- declare const corsHook: Hook;
7
- export default corsHook;
@@ -1,36 +0,0 @@
1
- // 相对导入
2
- import { setCorsOptions } from "../utils/cors";
3
- /**
4
- * CORS 跨域处理钩子
5
- * 设置跨域响应头并处理 OPTIONS 预检请求
6
- */
7
- const corsHook = {
8
- name: "cors",
9
- enable: true,
10
- deps: [],
11
- handler: async (befly, ctx) => {
12
- const req = ctx.req;
13
- // 合并默认配置和用户配置
14
- const defaultConfig = {
15
- origin: "*",
16
- methods: "GET, POST, OPTIONS",
17
- allowedHeaders: "Content-Type, Authorization, authorization, token",
18
- exposedHeaders: "Content-Range, X-Content-Range, Authorization, authorization, token",
19
- maxAge: 86400,
20
- credentials: "true"
21
- };
22
- const corsConfig = Object.assign({}, defaultConfig, befly.config && befly.config.cors ? befly.config.cors : {});
23
- // 设置 CORS 响应头
24
- const headers = setCorsOptions(req, corsConfig);
25
- ctx.corsHeaders = headers;
26
- // 处理 OPTIONS 预检请求
27
- if (req.method === "OPTIONS") {
28
- ctx.response = new Response(null, {
29
- status: 204,
30
- headers: headers
31
- });
32
- return;
33
- }
34
- }
35
- };
36
- export default corsHook;
@@ -1,10 +0,0 @@
1
- import type { Hook } from "../types/hook";
2
- /**
3
- * 请求参数解析钩子
4
- * - GET 请求:解析 URL 查询参数
5
- * - POST 请求:解析 JSON 或 XML 请求体
6
- * - 仅负责解析与合并参数;字段过滤/映射/校验由 validator hook 处理
7
- * - rawBody: true 时跳过解析,由 handler 自行处理原始请求
8
- */
9
- declare const parserHook: Hook;
10
- export default parserHook;
@@ -1,76 +0,0 @@
1
- // 外部依赖
2
- import { XMLParser } from "fast-xml-parser";
3
- import { ErrorResponse } from "../utils/response";
4
- const xmlParser = new XMLParser();
5
- /**
6
- * 请求参数解析钩子
7
- * - GET 请求:解析 URL 查询参数
8
- * - POST 请求:解析 JSON 或 XML 请求体
9
- * - 仅负责解析与合并参数;字段过滤/映射/校验由 validator hook 处理
10
- * - rawBody: true 时跳过解析,由 handler 自行处理原始请求
11
- */
12
- const parserHook = {
13
- name: "parser",
14
- enable: true,
15
- deps: ["auth"],
16
- handler: async (befly, ctx) => {
17
- if (!ctx.api)
18
- return;
19
- // rawBody 模式:跳过解析,保留原始请求供 handler 自行处理
20
- // 适用于:微信回调、支付回调、webhook 等需要手动解密/验签的场景
21
- if (ctx.api.rawBody) {
22
- ctx.body = {};
23
- return;
24
- }
25
- // GET 请求:解析查询参数
26
- if (ctx.req.method === "GET") {
27
- const url = new URL(ctx.req.url);
28
- const params = Object.fromEntries(url.searchParams);
29
- ctx.body = params;
30
- }
31
- else if (ctx.req.method === "POST") {
32
- // POST 请求:解析请求体
33
- const contentType = ctx.req.headers.get("content-type") || "";
34
- // 获取 URL 查询参数(POST 请求也可能带参数)
35
- const url = new URL(ctx.req.url);
36
- const queryParams = Object.fromEntries(url.searchParams);
37
- try {
38
- // JSON 格式
39
- if (contentType.includes("application/json")) {
40
- const body = (await ctx.req.json());
41
- // 合并 URL 参数和请求体(请求体优先)
42
- const merged = { ...queryParams, ...body };
43
- ctx.body = merged;
44
- }
45
- else if (contentType.includes("application/xml") || contentType.includes("text/xml")) {
46
- // XML 格式
47
- const text = await ctx.req.text();
48
- const parsed = xmlParser.parse(text);
49
- // 提取根节点内容(如 xml),使 body 扁平化
50
- const rootKey = Object.keys(parsed)[0];
51
- const body = rootKey && typeof parsed[rootKey] === "object" ? parsed[rootKey] : parsed;
52
- // 合并 URL 参数和请求体(请求体优先)
53
- const merged = { ...queryParams, ...body };
54
- ctx.body = merged;
55
- }
56
- else {
57
- // 不支持的 Content-Type
58
- ctx.response = ErrorResponse(ctx, "无效的请求参数格式", 1, null, {
59
- location: "content-type",
60
- value: contentType
61
- }, "parser");
62
- return;
63
- }
64
- }
65
- catch {
66
- // 解析失败:属于客户端输入错误,返回安全 detail(不回传异常栈/原始 body)
67
- ctx.response = ErrorResponse(ctx, "无效的请求参数格式", 1, null, {
68
- location: "body",
69
- reason: contentType.includes("application/json") ? "invalid_json" : contentType.includes("xml") ? "invalid_xml" : "invalid_body"
70
- }, "parser");
71
- return;
72
- }
73
- }
74
- }
75
- };
76
- export default parserHook;
@@ -1,10 +0,0 @@
1
- import type { Hook } from "../types/hook";
2
- /**
3
- * 权限检查钩子
4
- * - 接口无需权限(auth=false):直接通过
5
- * - 用户未登录:返回 401
6
- * - 开发者角色(dev):最高权限,直接通过
7
- * - 其他角色:检查 Redis 中的角色权限集合
8
- */
9
- declare const permissionHook: Hook;
10
- export default permissionHook;
@@ -1,64 +0,0 @@
1
- import { CacheKeys } from "../lib/cacheKeys";
2
- import { Logger } from "../lib/logger";
3
- // 相对导入
4
- import { ErrorResponse } from "../utils/response";
5
- /**
6
- * 权限检查钩子
7
- * - 接口无需权限(auth=false):直接通过
8
- * - 用户未登录:返回 401
9
- * - 开发者角色(dev):最高权限,直接通过
10
- * - 其他角色:检查 Redis 中的角色权限集合
11
- */
12
- const permissionHook = {
13
- name: "permission",
14
- enable: true,
15
- deps: ["validator"],
16
- handler: async (befly, ctx) => {
17
- if (!ctx.api)
18
- return;
19
- // 1. 接口无需权限
20
- if (ctx.api.auth === false) {
21
- return;
22
- }
23
- // 2. 用户未登录
24
- if (typeof ctx.user.id !== "number") {
25
- ctx.response = ErrorResponse(ctx, "未登录", 1, null, null, "auth");
26
- return;
27
- }
28
- // 3. 开发者权限(最高权限)
29
- if (ctx.user.roleCode === "dev") {
30
- return;
31
- }
32
- // 4. 角色权限检查
33
- // apiPath 在 apiHandler 中已统一生成并写入 ctx.route
34
- const apiPath = ctx.route;
35
- const roleCode = ctx.user.roleCode;
36
- let hasPermission = false;
37
- if (roleCode && befly.redis) {
38
- try {
39
- // 极简方案:每个角色一个 Set,直接判断成员是否存在
40
- const roleApisKey = CacheKeys.roleApis(roleCode);
41
- hasPermission = await befly.redis.sismember(roleApisKey, apiPath);
42
- }
43
- catch (err) {
44
- // Redis 异常:记录到 error 日志文件(不回传给客户端),并降级为拒绝访问
45
- Logger.error({
46
- event: "hook_permission_redis_error",
47
- apiPath: apiPath,
48
- roleCode: roleCode,
49
- err: err,
50
- msg: "hook permission redis error"
51
- });
52
- hasPermission = false;
53
- }
54
- }
55
- if (!hasPermission) {
56
- const apiNameLabel = typeof ctx.api.name === "string" && ctx.api.name.length > 0 ? ctx.api.name : null;
57
- const apiPathLabel = typeof apiPath === "string" && apiPath.length > 0 ? apiPath : null;
58
- const apiLabel = apiNameLabel ? apiNameLabel : apiPathLabel ? apiPathLabel : "未知接口";
59
- ctx.response = ErrorResponse(ctx, `无权访问 ${apiLabel} 接口`, 1, null, { apiLabel: apiLabel }, "permission");
60
- return;
61
- }
62
- }
63
- };
64
- export default permissionHook;
@@ -1,7 +0,0 @@
1
- import type { Hook } from "../types/hook";
2
- /**
3
- * 参数验证钩子
4
- * 根据 API 定义的 fields 和 required 验证请求参数
5
- */
6
- declare const validatorHook: Hook;
7
- export default validatorHook;
@@ -1,52 +0,0 @@
1
- // 相对导入
2
- import { Validator } from "../lib/validator";
3
- import { normalizeFieldDefinition } from "../utils/normalizeFieldDefinition";
4
- import { ErrorResponse } from "../utils/response";
5
- import { isPlainObject, snakeCase } from "../utils/util";
6
- /**
7
- * 参数验证钩子
8
- * 根据 API 定义的 fields 和 required 验证请求参数
9
- */
10
- const validatorHook = {
11
- name: "validator",
12
- enable: true,
13
- deps: ["parser"],
14
- handler: async (befly, ctx) => {
15
- if (!ctx.api)
16
- return;
17
- // 无需验证
18
- if (!ctx.api.fields) {
19
- return;
20
- }
21
- // 仅保留 fields 中声明的字段,并支持 snake_case 入参回退(例如 agent_id -> agentId);同时在同一次遍历中应用默认值
22
- if (isPlainObject(ctx.api.fields)) {
23
- const rawBody = isPlainObject(ctx.body) ? ctx.body : {};
24
- const nextBody = {};
25
- for (const [field, fieldDef] of Object.entries(ctx.api.fields)) {
26
- const normalized = normalizeFieldDefinition(fieldDef);
27
- let value = rawBody[field];
28
- if (value === undefined) {
29
- const snakeField = snakeCase(field);
30
- if (rawBody[snakeField] !== undefined) {
31
- value = rawBody[snakeField];
32
- }
33
- }
34
- // 字段未传值且定义了默认值时,应用默认值
35
- if (value === undefined && normalized.default !== null) {
36
- value = normalized.default;
37
- }
38
- if (value !== undefined) {
39
- nextBody[field] = value;
40
- }
41
- }
42
- ctx.body = nextBody;
43
- }
44
- // 验证参数
45
- const result = Validator.validate(ctx.body, ctx.api.fields, ctx.api.required || []);
46
- if (result.code !== 0) {
47
- ctx.response = ErrorResponse(ctx, result.firstError || "参数验证失败", 1, null, result.fieldErrors, "validator");
48
- return;
49
- }
50
- }
51
- };
52
- export default validatorHook;