befly 2.3.3 → 3.0.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 (87) hide show
  1. package/checks/conflict.ts +329 -0
  2. package/checks/table.ts +252 -0
  3. package/config/env.ts +218 -0
  4. package/config/fields.ts +55 -0
  5. package/config/regexAliases.ts +51 -0
  6. package/config/reserved.ts +96 -0
  7. package/main.ts +47 -0
  8. package/package.json +26 -11
  9. package/plugins/db.ts +60 -0
  10. package/plugins/logger.ts +28 -0
  11. package/plugins/redis.ts +47 -0
  12. package/scripts/syncDb/apply.ts +171 -0
  13. package/scripts/syncDb/constants.ts +71 -0
  14. package/scripts/syncDb/ddl.ts +189 -0
  15. package/scripts/syncDb/helpers.ts +173 -0
  16. package/scripts/syncDb/index.ts +203 -0
  17. package/scripts/syncDb/schema.ts +199 -0
  18. package/scripts/syncDb/sqlite.ts +50 -0
  19. package/scripts/syncDb/state.ts +106 -0
  20. package/scripts/syncDb/table.ts +214 -0
  21. package/scripts/syncDb/tableCreate.ts +148 -0
  22. package/scripts/syncDb/tests/constants.test.ts +105 -0
  23. package/scripts/syncDb/tests/ddl.test.ts +134 -0
  24. package/scripts/syncDb/tests/helpers.test.ts +70 -0
  25. package/scripts/syncDb/types.ts +92 -0
  26. package/scripts/syncDb/version.ts +73 -0
  27. package/scripts/syncDb.ts +10 -0
  28. package/tsconfig.json +58 -0
  29. package/types/addon.d.ts +53 -0
  30. package/types/api.d.ts +249 -0
  31. package/types/befly.d.ts +230 -0
  32. package/types/common.d.ts +215 -0
  33. package/types/context.d.ts +7 -0
  34. package/types/crypto.d.ts +23 -0
  35. package/types/database.d.ts +273 -0
  36. package/types/index.d.ts +450 -0
  37. package/types/index.ts +438 -0
  38. package/types/jwt.d.ts +99 -0
  39. package/types/logger.d.ts +43 -0
  40. package/types/plugin.d.ts +109 -0
  41. package/types/redis.d.ts +46 -0
  42. package/types/tool.d.ts +67 -0
  43. package/types/validator.d.ts +43 -0
  44. package/types/validator.ts +43 -0
  45. package/utils/colors.ts +221 -0
  46. package/utils/crypto.ts +308 -0
  47. package/utils/database.ts +348 -0
  48. package/utils/dbHelper.ts +713 -0
  49. package/utils/helper.ts +812 -0
  50. package/utils/index.ts +33 -0
  51. package/utils/jwt.ts +493 -0
  52. package/utils/logger.ts +191 -0
  53. package/utils/redisHelper.ts +321 -0
  54. package/utils/requestContext.ts +167 -0
  55. package/utils/sqlBuilder.ts +611 -0
  56. package/utils/validate.ts +493 -0
  57. package/utils/{xml.js → xml.ts} +100 -74
  58. package/.npmrc +0 -3
  59. package/.prettierignore +0 -2
  60. package/.prettierrc +0 -11
  61. package/apis/health/info.js +0 -49
  62. package/apis/tool/tokenCheck.js +0 -29
  63. package/bin/befly.js +0 -109
  64. package/bunfig.toml +0 -3
  65. package/checks/table.js +0 -206
  66. package/config/env.js +0 -64
  67. package/main.js +0 -579
  68. package/plugins/db.js +0 -46
  69. package/plugins/logger.js +0 -14
  70. package/plugins/redis.js +0 -32
  71. package/plugins/tool.js +0 -8
  72. package/scripts/syncDb.js +0 -752
  73. package/scripts/syncDev.js +0 -96
  74. package/system.js +0 -118
  75. package/tables/common.json +0 -16
  76. package/tables/tool.json +0 -6
  77. package/utils/api.js +0 -27
  78. package/utils/colors.js +0 -83
  79. package/utils/crypto.js +0 -260
  80. package/utils/index.js +0 -334
  81. package/utils/jwt.js +0 -387
  82. package/utils/logger.js +0 -143
  83. package/utils/redisHelper.js +0 -74
  84. package/utils/sqlBuilder.js +0 -498
  85. package/utils/sqlManager.js +0 -471
  86. package/utils/tool.js +0 -31
  87. package/utils/validate.js +0 -226
package/checks/table.js DELETED
@@ -1,206 +0,0 @@
1
- import path from 'node:path';
2
- import { Logger } from '../utils/logger.js';
3
- import { parseRule } from '../utils/index.js';
4
- import { __dirtables, getProjectDir } from '../system.js';
5
-
6
- // 所有校验函数均复用 utils/index.js 导出的实现
7
-
8
- export const checkTable = async () => {
9
- try {
10
- const tablesGlob = new Bun.Glob('*.json');
11
-
12
- // 统计信息
13
- let totalFiles = 0;
14
- let totalRules = 0;
15
- let validFiles = 0;
16
- let invalidFiles = 0;
17
-
18
- // 收集所有表文件
19
- const allTableFiles = [];
20
- const coreTableNames = new Set(); // 存储内核表文件名
21
-
22
- // 收集内核表字段定义文件
23
- for await (const file of tablesGlob.scan({
24
- cwd: __dirtables,
25
- absolute: true,
26
- onlyFiles: true
27
- })) {
28
- const fileName = path.basename(file, '.json');
29
- coreTableNames.add(fileName);
30
- allTableFiles.push({ file, type: 'core' });
31
- }
32
-
33
- // 收集项目表字段定义文件,并检查是否与内核表同名
34
- for await (const file of tablesGlob.scan({
35
- cwd: getProjectDir('tables'),
36
- absolute: true,
37
- onlyFiles: true
38
- })) {
39
- const fileName = path.basename(file, '.json');
40
-
41
- // 检查项目表是否与内核表同名
42
- if (coreTableNames.has(fileName)) {
43
- Logger.error(`项目表 ${fileName}.json 与内核表同名,项目表不能与内核表定义文件同名`);
44
- invalidFiles++;
45
- totalFiles++;
46
- continue;
47
- }
48
-
49
- allTableFiles.push({ file, type: 'project' });
50
- }
51
-
52
- // 保留字段列表
53
- const reservedFields = ['id', 'created_at', 'updated_at', 'deleted_at', 'state'];
54
-
55
- // 合并进行验证逻辑
56
- for (const { file, type } of allTableFiles) {
57
- totalFiles++;
58
- const fileName = path.basename(file);
59
- const fileBaseName = path.basename(file, '.json');
60
- const fileType = type === 'core' ? '内核' : '项目';
61
-
62
- try {
63
- // 1) 文件名小驼峰校验:必须以小写字母开头,后续可包含小写/数字,或多个 [大写+小写/数字] 片段
64
- // 示例:userTable、testCustomers、common
65
- const lowerCamelCaseRegex = /^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$/;
66
- if (!lowerCamelCaseRegex.test(fileBaseName)) {
67
- Logger.error(`${fileType}表 ${fileName} 文件名必须使用小驼峰命名(例如 testCustomers.json)`);
68
- // 命名不合规,按保留字段处理模式:记录错误并计为无效文件,继续下一个文件
69
- invalidFiles++;
70
- continue;
71
- }
72
-
73
- // 读取并解析 JSON 文件
74
- const table = await Bun.file(file).json();
75
- let fileValid = true;
76
- let fileRules = 0;
77
-
78
- // 检查 table 中的每个验证规则
79
- for (const [colKey, rule] of Object.entries(table)) {
80
- // 验证规则格式
81
- try {
82
- fileRules++;
83
- totalRules++;
84
-
85
- // 检查是否使用了保留字段
86
- if (reservedFields.includes(colKey)) {
87
- Logger.error(`${fileType}表 ${fileName} 文件包含保留字段 ${colKey},不能在表定义中使用以下字段: ${reservedFields.join(', ')}`);
88
- fileValid = false;
89
- }
90
-
91
- const allParts = rule.split('⚡');
92
-
93
- // 必须包含7个部分:显示名⚡类型⚡最小值⚡最大值⚡默认值⚡是否索引⚡正则约束
94
- if (allParts.length !== 7) {
95
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 字段规则格式错误,必须包含7个部分,当前包含${allParts.length}个部分`);
96
- fileValid = false;
97
- }
98
-
99
- const [fieldName, fieldType, fieldMin, fieldMax, fieldDefault, fieldIndex, fieldRegx] = allParts;
100
-
101
- // 第1个值:名称必须为中文、数字、字母
102
- if (!/^[\u4e00-\u9fa5a-zA-Z0-9 _-]+$/.test(fieldName)) {
103
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 字段名称 "${fieldName}" 格式错误,必须为中文、数字、字母、下划线、短横线`);
104
- fileValid = false;
105
- }
106
-
107
- // 第2个值:字段类型必须为string,number,text,array之一
108
- if (!['string', 'number', 'text', 'array'].includes(fieldType)) {
109
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 字段类型 "${fieldType}" 格式错误,必须为string、number、text、array之一`);
110
- fileValid = false;
111
- }
112
-
113
- // 第3/4个值:需要是 null 或 数字(并包含最小值<=最大值的约束)
114
- if (!(fieldMin === 'null' || !Number.isNaN(Number(fieldMin)))) {
115
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 最小值 "${fieldMin}" 格式错误,必须为null或数字`);
116
- fileValid = false;
117
- }
118
- if (!(fieldMax === 'null' || !Number.isNaN(Number(fieldMax)))) {
119
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 最大值 "${fieldMax}" 格式错误,必须为null或数字`);
120
- fileValid = false;
121
- }
122
-
123
- // 约束:当最小值与最大值均为数字时,要求最小值 <= 最大值
124
- if (fieldMin !== 'null' && fieldMax !== 'null') {
125
- if (Number(fieldMin) > Number(fieldMax)) {
126
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 最小值 "${fieldMin}" 不能大于最大值 "${fieldMax}"`);
127
- fileValid = false;
128
- }
129
- }
130
-
131
- // 第6个值:是否创建索引必须为0或1
132
- if (fieldIndex !== '0' && fieldIndex !== '1') {
133
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 索引标识 "${fieldIndex}" 格式错误,必须为0或1`);
134
- fileValid = false;
135
- }
136
-
137
- // 第7个值:必须为null或正则表达式
138
- if (fieldRegx !== 'null') {
139
- try {
140
- // 仅尝试构造以校验有效性
141
- // eslint-disable-next-line no-new
142
- new RegExp(fieldRegx);
143
- } catch (_) {
144
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 正则约束 "${fieldRegx}" 格式错误,必须为null或有效的正则表达式`);
145
- fileValid = false;
146
- }
147
- }
148
-
149
- // 第4个值与类型联动校验 + 默认值规则(精简实现)
150
- if (fieldType === 'text') {
151
- // text:min/max 必须为 null,默认值必须为 'null'
152
- if (fieldMin !== 'null') {
153
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 的 text 类型最小值必须为 null,当前为 "${fieldMin}"`);
154
- fileValid = false;
155
- }
156
- if (fieldMax !== 'null') {
157
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 的 text 类型最大长度必须为 null,当前为 "${fieldMax}"`);
158
- fileValid = false;
159
- }
160
- if (fieldDefault !== 'null') {
161
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 为 text 类型,默认值必须为 null,当前为 "${fieldDefault}"`);
162
- fileValid = false;
163
- }
164
- } else if (fieldType === 'string' || fieldType === 'array') {
165
- if (Number.isNaN(Number(fieldMax))) {
166
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 为 string,array 类型,最大长度必须为数字,当前为 "${fieldMax}"`);
167
- fileValid = false;
168
- }
169
- const maxVal = parseInt(fieldMax, 10);
170
- if (maxVal > 65535) {
171
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 最大长度 ${fieldMax} 越界,string,array 类型长度必须在 1..65535 范围内`);
172
- fileValid = false;
173
- }
174
- } else if (fieldType === 'number') {
175
- if (Number.isNaN(Number(fieldDefault))) {
176
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 为 number 类型,默认值必须为数字,当前为 "${fieldDefault}"`);
177
- fileValid = false;
178
- }
179
- }
180
- } catch (error) {
181
- Logger.error(`${fileType}表 ${fileName} 文件 ${colKey} 验证规则解析失败: ${error.message}`);
182
- fileValid = false;
183
- }
184
- }
185
-
186
- if (fileValid) {
187
- validFiles++;
188
- } else {
189
- invalidFiles++;
190
- }
191
- } catch (error) {
192
- Logger.error(`${fileType}表 ${fileName} 解析失败: ${error.message}`);
193
- invalidFiles++;
194
- }
195
- }
196
-
197
- if (invalidFiles > 0) {
198
- return false;
199
- } else {
200
- return true;
201
- }
202
- } catch (error) {
203
- Logger.error(`Tables 检查过程中出错:`, error);
204
- return false;
205
- }
206
- };
package/config/env.js DELETED
@@ -1,64 +0,0 @@
1
- export const Env = {
2
- // 项目模式
3
- NODE_ENV: process.env.NODE_ENV,
4
- // 应用名称
5
- APP_NAME: process.env.APP_NAME,
6
- // 加密盐
7
- MD5_SALT: process.env.MD5_SALT,
8
- // 监听端口
9
- APP_PORT: Number(process.env.APP_PORT),
10
- // 监听主机
11
- APP_HOST: process.env.APP_HOST,
12
- // 超级管理员密码
13
- DEV_PASSWORD: process.env.DEV_PASSWORD,
14
- // 请求体大小 10M
15
- BODY_LIMIT: Number(process.env.BODY_LIMIT),
16
- // 是否进行参数验证
17
- PARAMS_CHECK: process.env.PARAMS_CHECK,
18
- // 日志等级
19
- LOG_LEVEL: process.env.LOG_LEVEL,
20
- LOG_EXCLUDE_FIELDS: process.env.LOG_EXCLUDE_FIELDS,
21
- LOG_DIR: process.env.LOG_DIR,
22
- LOG_TO_CONSOLE: Number(process.env.LOG_TO_CONSOLE),
23
- LOG_MAX_SIZE: Number(process.env.LOG_MAX_SIZE),
24
- // 时区
25
- TZ: process.env.TZ,
26
- // 数据库配置
27
- DB_ENABLE: Number(process.env.DB_ENABLE),
28
- // 通用数据库连接参数
29
- DB_TYPE: process.env.DB_TYPE, // sqlite | mysql | postgresql
30
- DB_HOST: process.env.DB_HOST,
31
- DB_PORT: Number(process.env.DB_PORT),
32
- DB_USER: process.env.DB_USER,
33
- DB_PASS: process.env.DB_PASS,
34
- DB_NAME: process.env.DB_NAME,
35
- DB_DEBUG: Number(process.env.DB_DEBUG),
36
- DB_POOL_MAX: Number(process.env.DB_POOL_MAX),
37
- // Redis配置
38
- REDIS_URL: process.env.REDIS_URL,
39
- REDIS_ENABLE: Number(process.env.REDIS_ENABLE),
40
- REDIS_HOST: process.env.REDIS_HOST,
41
- REDIS_PORT: Number(process.env.REDIS_PORT),
42
- REDIS_USERNAME: process.env.REDIS_USERNAME,
43
- REDIS_PASSWORD: process.env.REDIS_PASSWORD,
44
- REDIS_DB: Number(process.env.REDIS_DB),
45
- REDIS_KEY_PREFIX: process.env.REDIS_KEY_PREFIX,
46
- // JWT配置
47
- JWT_SECRET: process.env.JWT_SECRET,
48
- JWT_EXPIRES_IN: process.env.JWT_EXPIRES_IN,
49
- JWT_ALGORITHM: process.env.JWT_ALGORITHM,
50
- // 邮件配置
51
- MAIL_HOST: process.env.MAIL_HOST,
52
- MAIL_PORT: Number(process.env.MAIL_PORT),
53
- MAIL_POOL: process.env.MAIL_POOL,
54
- MAIL_SECURE: process.env.MAIL_SECURE,
55
- MAIL_USER: process.env.MAIL_USER,
56
- MAIL_PASS: process.env.MAIL_PASS,
57
- MAIL_SENDER: process.env.MAIL_SENDER,
58
- MAIL_ADDRESS: process.env.MAIL_ADDRESS,
59
- // 同步脚本开关(用于 core/scripts/syncDb.js)
60
- SYNC_MERGE_ALTER: process.env.SYNC_MERGE_ALTER,
61
- SYNC_ONLINE_INDEX: process.env.SYNC_ONLINE_INDEX,
62
- SYNC_DISALLOW_SHRINK: process.env.SYNC_DISALLOW_SHRINK,
63
- SYNC_ALLOW_TYPE_CHANGE: process.env.SYNC_ALLOW_TYPE_CHANGE
64
- };