befly 3.76.0 → 3.76.2

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 (155) hide show
  1. package/Befly.js +159 -0
  2. package/README.md +50 -11
  3. package/apis/admin/delete.js +1 -3
  4. package/apis/admin/insert.js +2 -1
  5. package/apis/admin/select.js +2 -7
  6. package/apis/admin/update.js +3 -8
  7. package/apis/api/select.js +2 -7
  8. package/apis/auth/login.js +16 -20
  9. package/apis/dict/delete.js +1 -1
  10. package/apis/dict/detail.js +1 -3
  11. package/apis/dict/select.js +1 -2
  12. package/apis/dict/update.js +1 -1
  13. package/apis/dictType/delete.js +1 -1
  14. package/apis/dictType/detail.js +1 -1
  15. package/apis/dictType/insert.js +1 -1
  16. package/apis/dictType/select.js +2 -7
  17. package/apis/dictType/update.js +2 -2
  18. package/apis/email/config.js +4 -7
  19. package/apis/email/logList.js +2 -7
  20. package/apis/email/send.js +1 -2
  21. package/apis/email/verify.js +1 -3
  22. package/apis/loginLog/select.js +2 -7
  23. package/apis/menu/select.js +2 -7
  24. package/apis/operateLog/select.js +2 -7
  25. package/apis/role/apiSave.js +2 -2
  26. package/apis/role/menuSave.js +2 -2
  27. package/apis/role/select.js +2 -7
  28. package/apis/source/imageList.js +2 -5
  29. package/apis/tongJi/dailyReport.js +12 -13
  30. package/apis/tongJi/dailyReportSelect.js +1 -2
  31. package/apis/tongJi/dailyStats.js +1 -1
  32. package/apis/tongJi/dailyStatsDistribution.js +2 -2
  33. package/apis/tongJi/errorList.js +1 -2
  34. package/apis/tongJi/errorReport.js +1 -2
  35. package/apis/tongJi/projectDelete.js +1 -3
  36. package/apis/tongJi/projectSelect.js +2 -4
  37. package/apis/tongJi/projectUpdate.js +2 -2
  38. package/apis/upload/file.js +7 -5
  39. package/checks/api.js +43 -66
  40. package/checks/config.js +17 -12
  41. package/checks/corns.js +28 -46
  42. package/checks/field.js +18 -0
  43. package/checks/items.js +16 -60
  44. package/checks/menu.js +28 -39
  45. package/checks/table.js +106 -26
  46. package/checks/validation.js +13 -0
  47. package/configs/beflyConfig.json +6 -6
  48. package/configs/constConfig.js +2 -63
  49. package/exports.js +2 -0
  50. package/hooks/auth.js +11 -7
  51. package/hooks/parser.js +55 -59
  52. package/hooks/permission.js +5 -2
  53. package/hooks/rateLimit.js +25 -62
  54. package/hooks/validator.js +43 -31
  55. package/index.js +43 -344
  56. package/{lib → libs}/cacheHelper.js +3 -8
  57. package/libs/cron.js +60 -0
  58. package/libs/logger/index.js +1 -0
  59. package/libs/logger/logger.js +245 -0
  60. package/libs/logger/sanitize.js +115 -0
  61. package/{lib → libs/mysql}/dbHelper.js +100 -73
  62. package/{lib → libs/mysql}/dbParse.js +16 -9
  63. package/{lib → libs/mysql}/dbUtil.js +15 -32
  64. package/libs/mysql/error.js +29 -0
  65. package/libs/mysql/index.js +6 -0
  66. package/libs/mysql/is.js +29 -0
  67. package/libs/mysql/mysql.js +43 -0
  68. package/libs/mysql/sql/identifier.js +85 -0
  69. package/libs/mysql/sql/index.js +2 -0
  70. package/{lib → libs/mysql/sql}/sqlBuilder.js +2 -3
  71. package/libs/mysql/util.js +44 -0
  72. package/libs/redis/index.js +2 -0
  73. package/libs/redis/redis.js +204 -0
  74. package/libs/redis/redisError.js +8 -0
  75. package/libs/tableModel.js +72 -0
  76. package/libs/tool.js +33 -0
  77. package/libs/validator/compiler.js +248 -0
  78. package/libs/validator/index.js +10 -0
  79. package/libs/validator/parser.js +173 -0
  80. package/libs/validator/util.js +5 -0
  81. package/package.json +10 -8
  82. package/paths.js +2 -3
  83. package/plugins/cache.js +2 -1
  84. package/plugins/email.js +4 -4
  85. package/plugins/mysql.js +5 -15
  86. package/plugins/redis.js +4 -12
  87. package/router/api.js +14 -10
  88. package/router/root.js +14 -0
  89. package/router/static.js +3 -3
  90. package/schemas/api.json +99 -0
  91. package/schemas/config.json +255 -0
  92. package/schemas/corn.json +39 -0
  93. package/schemas/item.json +43 -0
  94. package/schemas/menu.json +44 -0
  95. package/schemas/table.json +80 -0
  96. package/scripts/syncDb/apply.js +87 -0
  97. package/scripts/syncDb/ddl.js +43 -0
  98. package/scripts/syncDb/index.js +175 -30
  99. package/scripts/syncDb/model.js +60 -0
  100. package/scripts/syncDb/plan.js +160 -0
  101. package/scripts/syncDb/preflight.js +98 -0
  102. package/scripts/syncDb/report.js +177 -162
  103. package/scripts/syncDb/snapshot.js +118 -0
  104. package/sync/syncUtil.js +7 -13
  105. package/tables/admin.json +51 -53
  106. package/tables/api.json +29 -40
  107. package/tables/dailyReport.json +85 -73
  108. package/tables/dict.json +27 -39
  109. package/tables/dictType.json +20 -34
  110. package/tables/emailLog.json +49 -47
  111. package/tables/errorReport.json +86 -60
  112. package/tables/file.json +47 -50
  113. package/tables/loginLog.json +68 -55
  114. package/tables/menu.json +20 -34
  115. package/tables/operateLog.json +53 -47
  116. package/tables/project.json +18 -30
  117. package/tables/role.json +33 -37
  118. package/utils/cors.js +37 -41
  119. package/utils/deepMerge.js +3 -1
  120. package/utils/error.js +1 -56
  121. package/utils/id.js +44 -0
  122. package/utils/is.js +6 -243
  123. package/utils/response.js +12 -1
  124. package/utils/scanFiles.js +13 -4
  125. package/utils/scanSources.js +58 -20
  126. package/utils/util.js +11 -163
  127. package/apis/_apis.js +0 -20
  128. package/apis/auth/sendSmsCode.js +0 -24
  129. package/apis/role/delete.js +0 -41
  130. package/apis/role/insert.js +0 -45
  131. package/apis/role/save.js +0 -36
  132. package/apis/role/update.js +0 -66
  133. package/configs/regexpAlias.json +0 -55
  134. package/lib/connect.js +0 -119
  135. package/lib/logger.js +0 -430
  136. package/lib/redisHelper.js +0 -399
  137. package/lib/validator.js +0 -274
  138. package/lib/xmlParse.js +0 -149
  139. package/plugins/config.js +0 -13
  140. package/plugins/cron.js +0 -115
  141. package/plugins/logger.js +0 -17
  142. package/plugins/tool.js +0 -131
  143. package/plugins/xmlParse.js +0 -10
  144. package/schemas/config.js +0 -67
  145. package/scripts/syncDb/context.js +0 -120
  146. package/scripts/syncDb/diff.js +0 -279
  147. package/scripts/syncDb/transform.js +0 -113
  148. package/sql/befly.sql +0 -271
  149. package/utils/email.js +0 -3
  150. package/utils/fieldClear.js +0 -22
  151. package/utils/formatValidationIssues.js +0 -28
  152. package/utils/getClientIp.js +0 -47
  153. package/utils/loggerUtils.js +0 -196
  154. package/utils/regexpUtil.js +0 -52
  155. /package/{lib → libs}/smtpText.js +0 -0
@@ -1,41 +0,0 @@
1
- import { getRoleById, systemRoleCodes } from "./_role.js";
2
-
3
- export default {
4
- name: "删除角色",
5
- method: "POST",
6
- body: "none",
7
- auth: true,
8
- fields: {
9
- id: { name: "ID", input: "integer", min: 1, max: null }
10
- },
11
- required: ["id"],
12
- handler: async (befly, ctx) => {
13
- const role = await getRoleById(befly, ctx.body.id, ["code"]);
14
-
15
- if (!role.data?.code) {
16
- return befly.tool.No("角色不存在");
17
- }
18
-
19
- if (systemRoleCodes.includes(role.data.code)) {
20
- return befly.tool.No(`系统角色 [${role.data.code}] 不允许删除`);
21
- }
22
-
23
- const adminList = await befly.mysql.getList({
24
- table: "beflyAdmin",
25
- where: { roleCode: role.data.code }
26
- });
27
-
28
- if (adminList.data.total > 0) {
29
- return befly.tool.No("该角色已分配给用户,无法删除");
30
- }
31
-
32
- await befly.mysql.delData({
33
- table: "beflyRole",
34
- where: { id: ctx.body.id }
35
- });
36
-
37
- await befly.cache.deleteRoleApis(role.data.code);
38
-
39
- return befly.tool.Yes("操作成功");
40
- }
41
- };
@@ -1,45 +0,0 @@
1
- import roleTable from "#befly/tables/role.json";
2
-
3
- export default {
4
- name: "创建角色",
5
- method: "POST",
6
- body: "none",
7
- auth: true,
8
- fields: {
9
- name: roleTable.name,
10
- code: roleTable.code,
11
- description: roleTable.description,
12
- menus: roleTable.menus,
13
- apis: roleTable.apis,
14
- sort: roleTable.sort
15
- },
16
- required: [],
17
- handler: async (befly, ctx) => {
18
- const menuPaths = ctx.body.menus || [];
19
- const apiPaths = ctx.body.apis || [];
20
- const existing = await befly.mysql.getOne({
21
- table: "beflyRole",
22
- where: { code: ctx.body.code }
23
- });
24
-
25
- if (existing.data?.id) {
26
- return befly.tool.No("角色代码已存在");
27
- }
28
-
29
- const roleId = await befly.mysql.insData({
30
- table: "beflyRole",
31
- data: {
32
- name: ctx.body.name,
33
- code: ctx.body.code,
34
- description: ctx.body.description,
35
- menus: menuPaths,
36
- apis: apiPaths,
37
- sort: ctx.body.sort
38
- }
39
- });
40
-
41
- await befly.cache.refreshRoleApis(ctx.body.code, apiPaths);
42
-
43
- return befly.tool.Yes("操作成功", { id: roleId.data });
44
- }
45
- };
package/apis/role/save.js DELETED
@@ -1,36 +0,0 @@
1
- import adminTable from "#befly/tables/admin.json";
2
- import roleTable from "#befly/tables/role.json";
3
-
4
- import { getRoleByCode } from "./_role.js";
5
-
6
- export default {
7
- name: "角色保存",
8
- method: "POST",
9
- body: "none",
10
- auth: true,
11
- fields: {
12
- adminId: adminTable.id,
13
- roleCode: roleTable.code
14
- },
15
- required: ["adminId", "roleCode"],
16
- handler: async (befly, ctx) => {
17
- const role = await getRoleByCode(befly, ctx.body.roleCode);
18
-
19
- if (!role.data?.id) {
20
- return befly.tool.No("角色不存在");
21
- }
22
-
23
- const roleType = role.data.code === "dev" || role.data.code === "admin" ? "admin" : "user";
24
-
25
- await befly.mysql.updData({
26
- table: "beflyAdmin",
27
- where: { id: ctx.body.adminId },
28
- data: {
29
- roleCode: role.data.code,
30
- roleType: roleType
31
- }
32
- });
33
-
34
- return befly.tool.Yes("操作成功");
35
- }
36
- };
@@ -1,66 +0,0 @@
1
- import roleTable from "#befly/tables/role.json";
2
-
3
- import { getRoleById } from "./_role.js";
4
-
5
- export default {
6
- name: "更新角色",
7
- method: "POST",
8
- body: "none",
9
- auth: true,
10
- fields: {
11
- id: roleTable.id,
12
- name: roleTable.name,
13
- code: roleTable.code,
14
- description: roleTable.description,
15
- menus: roleTable.menus,
16
- apis: roleTable.apis,
17
- sort: roleTable.sort
18
- },
19
- required: ["id"],
20
- handler: async (befly, ctx) => {
21
- const role = await getRoleById(befly, ctx.body.id);
22
-
23
- if (!role.data?.id) {
24
- return befly.tool.No("角色不存在");
25
- }
26
-
27
- if (ctx.body.code !== undefined) {
28
- const existing = await befly.mysql.getOne({
29
- table: "beflyRole",
30
- where: {
31
- code: ctx.body.code,
32
- id$not: ctx.body.id
33
- }
34
- });
35
-
36
- if (existing.data?.id) {
37
- return befly.tool.No("角色代码已被其他角色使用");
38
- }
39
- }
40
-
41
- const roleCode = ctx.body.code === undefined ? role.data.code : ctx.body.code;
42
- const apiPaths = ctx.body.apis === undefined ? role.data.apis || [] : ctx.body.apis;
43
- const menuPaths = ctx.body.menus === undefined ? role.data.menus || [] : ctx.body.menus;
44
-
45
- await befly.mysql.updData({
46
- table: "beflyRole",
47
- where: { id: ctx.body.id },
48
- data: {
49
- name: ctx.body.name,
50
- code: roleCode,
51
- description: ctx.body.description,
52
- menus: menuPaths,
53
- apis: apiPaths,
54
- sort: ctx.body.sort
55
- }
56
- });
57
-
58
- if (role.data.code !== roleCode) {
59
- await befly.cache.deleteRoleApis(role.data.code);
60
- }
61
-
62
- await befly.cache.refreshRoleApis(roleCode, apiPaths);
63
-
64
- return befly.tool.Yes("操作成功");
65
- }
66
- };
@@ -1,55 +0,0 @@
1
- {
2
- "number": "^\\d+$",
3
- "integer": "^-?\\d+$",
4
- "float": "^-?\\d+(\\.\\d+)?$",
5
- "positive": "^[1-9]\\d*$",
6
- "negative": "^-\\d+$",
7
- "zero": "^0$",
8
- "word": "^[a-zA-Z]+$",
9
- "alphanumeric": "^[a-zA-Z0-9]+$",
10
- "alphanumeric_": "^[a-zA-Z0-9_]+$",
11
- "alphanumericDash_": "^[a-zA-Z0-9_-]+$",
12
- "lowercase": "^[a-z]+$",
13
- "uppercase": "^[A-Z]+$",
14
- "chinese": "^[\\u4e00-\\u9fa5]+$",
15
- "chineseWord": "^[\\u4e00-\\u9fa5a-zA-Z]+$",
16
- "email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
17
- "phone": "^1[3-9]\\d{9}$",
18
- "telephone": "^0\\d{2,3}-?\\d{7,8}$",
19
- "url": "^https?://",
20
- "ip": "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$",
21
- "ipv6": "^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$",
22
- "domain": "^(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$",
23
- "uuid": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
24
- "hex": "^[0-9a-fA-F]+$",
25
- "base64": "^[A-Za-z0-9+/=]+$",
26
- "md5": "^[a-f0-9]{32}$",
27
- "sha1": "^[a-f0-9]{40}$",
28
- "sha256": "^[a-f0-9]{64}$",
29
- "date": "^\\d{4}-\\d{2}-\\d{2}$",
30
- "time": "^\\d{2}:\\d{2}:\\d{2}$",
31
- "datetime": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}",
32
- "year": "^\\d{4}$",
33
- "month": "^(0[1-9]|1[0-2])$",
34
- "day": "^(0[1-9]|[12]\\d|3[01])$",
35
- "variable": "^[a-zA-Z_][a-zA-Z0-9_]*$",
36
- "constant": "^[A-Z][A-Z0-9_]*$",
37
- "package": "^[a-z][a-z0-9-]*$",
38
- "idCard": "^\\d{17}[\\dXx]$",
39
- "passport": "^[a-zA-Z0-9]{5,17}$",
40
- "bankCard": "^\\d{16,19}$",
41
- "wechat": "^[a-zA-Z][a-zA-Z0-9_-]{5,19}$",
42
- "qq": "^[1-9]\\d{4,10}$",
43
- "alipay": "^(1[3-9]\\d{9}|[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})$",
44
- "username": "^[a-zA-Z][a-zA-Z0-9_]{3,19}$",
45
- "nickname": "^[\\u4e00-\\u9fa5a-zA-Z0-9]{2,20}$",
46
- "passwordWeak": "^.{6,}$",
47
- "passwordMedium": "^(?=.*[a-zA-Z])(?=.*\\d).{8,}$",
48
- "passwordStrong": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*]).{8,}$",
49
- "licensePlate": "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$",
50
- "postalCode": "^\\d{6}$",
51
- "semver": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$",
52
- "colorHex": "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$",
53
- "empty": "^$",
54
- "notempty": ".+"
55
- }
package/lib/connect.js DELETED
@@ -1,119 +0,0 @@
1
- /**
2
- * 负责管理数据库和 Redis 连接
3
- */
4
-
5
- import { RedisClient, SQL } from "bun";
6
-
7
- import { createError } from "../utils/error.js";
8
- import { getRunMode } from "../utils/util.js";
9
- import { Logger } from "./logger.js";
10
-
11
- function buildRedisUrl(config) {
12
- if (config.username) {
13
- const encodedUser = encodeURIComponent(config.username);
14
- const encodedPass = encodeURIComponent(config.password || "");
15
- return `redis://${encodedUser}:${encodedPass}@${config.hostname}:${config.port}/${config.db}`;
16
- }
17
-
18
- if (config.password) {
19
- const encodedPass = encodeURIComponent(config.password);
20
- return `redis://:${encodedPass}@${config.hostname}:${config.port}/${config.db}`;
21
- }
22
-
23
- return `redis://${config.hostname}:${config.port}/${config.db}`;
24
- }
25
-
26
- /**
27
- * 连接管理器
28
- */
29
- export class Connect {
30
- static mysqlClient = null;
31
- static redisClient = null;
32
-
33
- /**
34
- * 获取数据库客户端
35
- * @returns 数据库客户端
36
- */
37
- static getMysql() {
38
- return this.mysqlClient;
39
- }
40
-
41
- /**
42
- * 获取 Redis 客户端
43
- * @returns Redis 客户端
44
- */
45
- static getRedis() {
46
- return this.redisClient;
47
- }
48
-
49
- static async handleConnectError(clientKey, label, subsystem, hostname, error) {
50
- await this[clientKey]?.close();
51
- this[clientKey] = null;
52
- throw createError(`${label} 连接失败 (${hostname})`, { cause: error, code: "runtime", subsystem: subsystem, operation: "connect", runMode: getRunMode() });
53
- }
54
-
55
- /**
56
- * 连接数据库
57
- * @param config - 数据库配置
58
- */
59
- static async connectMysql(config) {
60
- try {
61
- this.mysqlClient = new SQL({
62
- adapter: "mysql",
63
- hostname: config.hostname,
64
- port: config.port,
65
- database: config.database,
66
- username: config.username,
67
- password: config.password,
68
- max: config.max,
69
- bigint: true,
70
- idleTimeout: config.idleTimeout,
71
- maxLifetime: config.maxLifetime,
72
- connectionTimeout: config.connectionTimeout,
73
- onclose: (client, err) => {
74
- if (err) {
75
- Logger.warn(`MySQL 连接关闭:${err.message ?? err}`);
76
- }
77
- }
78
- });
79
-
80
- await this.mysqlClient`SELECT 1`;
81
- } catch (error) {
82
- await this.handleConnectError("mysqlClient", "Mysql", "mysql", config.hostname, error);
83
- }
84
- }
85
-
86
- /**
87
- * 连接 Redis
88
- * @param config - Redis 配置
89
- */
90
- static async connectRedis(config) {
91
- try {
92
- this.redisClient = new RedisClient(buildRedisUrl(config));
93
- // Called when disconnected from Redis server
94
- this.redisClient.onclose = (error) => {
95
- if (error) {
96
- Logger.warn(`Redis 断开连接:${error.message ?? error}`);
97
- } else {
98
- Logger.warn("Redis 断开连接");
99
- }
100
- };
101
-
102
- // Eagerly verify the connection before returning
103
- await this.redisClient.ping();
104
- } catch (error) {
105
- await this.handleConnectError("redisClient", "Redis", "redis", config.hostname, error);
106
- }
107
- }
108
-
109
- /**
110
- * 断开连接
111
- */
112
- static async disconnect() {
113
- await this.mysqlClient?.close();
114
- this.mysqlClient = null;
115
-
116
- await this.redisClient?.close();
117
- this.redisClient = null;
118
- }
119
- }