befly 2.3.3 → 3.0.0

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 (93) hide show
  1. package/apis/health/info.ts +64 -0
  2. package/apis/tool/tokenCheck.ts +51 -0
  3. package/bin/befly.ts +202 -0
  4. package/checks/conflict.ts +408 -0
  5. package/checks/{table.js → table.ts} +139 -61
  6. package/config/env.ts +218 -0
  7. package/config/reserved.ts +96 -0
  8. package/main.ts +101 -0
  9. package/package.json +44 -8
  10. package/plugins/{db.js → db.ts} +24 -11
  11. package/plugins/logger.ts +28 -0
  12. package/plugins/redis.ts +51 -0
  13. package/plugins/tool.ts +34 -0
  14. package/scripts/syncDb/apply.ts +171 -0
  15. package/scripts/syncDb/constants.ts +70 -0
  16. package/scripts/syncDb/ddl.ts +182 -0
  17. package/scripts/syncDb/helpers.ts +172 -0
  18. package/scripts/syncDb/index.ts +215 -0
  19. package/scripts/syncDb/schema.ts +199 -0
  20. package/scripts/syncDb/sqlite.ts +50 -0
  21. package/scripts/syncDb/state.ts +104 -0
  22. package/scripts/syncDb/table.ts +204 -0
  23. package/scripts/syncDb/tableCreate.ts +142 -0
  24. package/scripts/syncDb/tests/constants.test.ts +104 -0
  25. package/scripts/syncDb/tests/ddl.test.ts +134 -0
  26. package/scripts/syncDb/tests/helpers.test.ts +70 -0
  27. package/scripts/syncDb/types.ts +92 -0
  28. package/scripts/syncDb/version.ts +73 -0
  29. package/scripts/syncDb.ts +9 -0
  30. package/scripts/{syncDev.js → syncDev.ts} +41 -25
  31. package/system.ts +149 -0
  32. package/tables/_common.json +21 -0
  33. package/tables/admin.json +10 -0
  34. package/tsconfig.json +58 -0
  35. package/types/api.d.ts +246 -0
  36. package/types/befly.d.ts +234 -0
  37. package/types/common.d.ts +215 -0
  38. package/types/context.ts +167 -0
  39. package/types/crypto.d.ts +23 -0
  40. package/types/database.d.ts +278 -0
  41. package/types/index.d.ts +16 -0
  42. package/types/index.ts +459 -0
  43. package/types/jwt.d.ts +99 -0
  44. package/types/logger.d.ts +43 -0
  45. package/types/plugin.d.ts +109 -0
  46. package/types/redis.d.ts +44 -0
  47. package/types/tool.d.ts +67 -0
  48. package/types/validator.d.ts +45 -0
  49. package/utils/addonHelper.ts +60 -0
  50. package/utils/api.ts +23 -0
  51. package/utils/{colors.js → colors.ts} +79 -21
  52. package/utils/crypto.ts +308 -0
  53. package/utils/datetime.ts +51 -0
  54. package/utils/dbHelper.ts +142 -0
  55. package/utils/errorHandler.ts +68 -0
  56. package/utils/index.ts +46 -0
  57. package/utils/jwt.ts +493 -0
  58. package/utils/logger.ts +284 -0
  59. package/utils/objectHelper.ts +68 -0
  60. package/utils/pluginHelper.ts +62 -0
  61. package/utils/redisHelper.ts +338 -0
  62. package/utils/response.ts +38 -0
  63. package/utils/{sqlBuilder.js → sqlBuilder.ts} +233 -97
  64. package/utils/sqlHelper.ts +447 -0
  65. package/utils/tableHelper.ts +167 -0
  66. package/utils/tool.ts +230 -0
  67. package/utils/typeHelper.ts +101 -0
  68. package/utils/validate.ts +451 -0
  69. package/utils/{xml.js → xml.ts} +100 -74
  70. package/.npmrc +0 -3
  71. package/.prettierignore +0 -2
  72. package/.prettierrc +0 -11
  73. package/apis/health/info.js +0 -49
  74. package/apis/tool/tokenCheck.js +0 -29
  75. package/bin/befly.js +0 -109
  76. package/config/env.js +0 -64
  77. package/main.js +0 -579
  78. package/plugins/logger.js +0 -14
  79. package/plugins/redis.js +0 -32
  80. package/plugins/tool.js +0 -8
  81. package/scripts/syncDb.js +0 -752
  82. package/system.js +0 -118
  83. package/tables/common.json +0 -16
  84. package/tables/tool.json +0 -6
  85. package/utils/api.js +0 -27
  86. package/utils/crypto.js +0 -260
  87. package/utils/index.js +0 -334
  88. package/utils/jwt.js +0 -387
  89. package/utils/logger.js +0 -143
  90. package/utils/redisHelper.js +0 -74
  91. package/utils/sqlManager.js +0 -471
  92. package/utils/tool.js +0 -31
  93. package/utils/validate.js +0 -226
package/utils/tool.ts ADDED
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Tool 工具类 - TypeScript 版本
3
+ * 提供数据处理的便捷方法
4
+ */
5
+
6
+ import { omitFields } from './index.js';
7
+ import type { BeflyContext } from '../types/befly.js';
8
+
9
+ /**
10
+ * 数据对象类型
11
+ */
12
+ type DataObject = Record<string, any>;
13
+
14
+ /**
15
+ * 工具类:通过构造函数注入 befly
16
+ */
17
+ export class Tool {
18
+ private befly: BeflyContext;
19
+
20
+ /**
21
+ * 构造函数
22
+ * @param befly - Befly 上下文
23
+ */
24
+ constructor(befly: BeflyContext) {
25
+ this.befly = befly;
26
+ }
27
+
28
+ /**
29
+ * 处理更新数据
30
+ * - 移除 id、created_at、deleted_at 字段
31
+ * - 添加 updated_at 时间戳
32
+ * @param data - 原始数据
33
+ * @returns 处理后的数据
34
+ */
35
+ async updData(data: DataObject): Promise<DataObject> {
36
+ const now = Date.now();
37
+ const cleaned = omitFields(data ?? {}, ['id', 'created_at', 'deleted_at'], [undefined]);
38
+ return { ...cleaned, updated_at: now };
39
+ }
40
+
41
+ /**
42
+ * 处理插入数据
43
+ * - 生成唯一 ID
44
+ * - 添加 created_at 和 updated_at 时间戳
45
+ * - 移除 undefined 字段
46
+ * @param data - 原始数据(支持单个对象或数组)
47
+ * @returns 处理后的数据
48
+ */
49
+ async insData(data: DataObject | DataObject[]): Promise<DataObject | DataObject[]> {
50
+ const now = Date.now();
51
+ const genId = async (): Promise<number> => await this.befly.redis.genTimeID();
52
+
53
+ if (Array.isArray(data)) {
54
+ return await Promise.all(
55
+ data.map(async (item) => ({
56
+ ...omitFields(item ?? {}, [], [undefined]),
57
+ id: await genId(),
58
+ created_at: now,
59
+ updated_at: now,
60
+ state: 0
61
+ }))
62
+ );
63
+ } else {
64
+ const cleaned = omitFields(data ?? {}, [], [undefined]);
65
+ return {
66
+ ...cleaned,
67
+ id: await genId(),
68
+ created_at: now,
69
+ updated_at: now,
70
+ state: 0
71
+ };
72
+ }
73
+ }
74
+
75
+ /**
76
+ * 处理删除数据(软删除)
77
+ * - 设置 deleted_at 时间戳
78
+ * - 添加 updated_at 时间戳
79
+ * @returns 处理后的数据
80
+ */
81
+ async delData(): Promise<DataObject> {
82
+ const now = Date.now();
83
+ return {
84
+ deleted_at: now,
85
+ updated_at: now,
86
+ state: 1
87
+ };
88
+ }
89
+
90
+ /**
91
+ * 批量生成 ID
92
+ * @param count - 生成数量
93
+ * @returns ID 数组
94
+ */
95
+ async genIds(count: number): Promise<number[]> {
96
+ const ids: number[] = [];
97
+ for (let i = 0; i < count; i++) {
98
+ ids.push(await this.befly.redis.genTimeID());
99
+ }
100
+ return ids;
101
+ }
102
+
103
+ /**
104
+ * 清理数据对象
105
+ * - 移除 undefined、null、空字符串
106
+ * @param data - 原始数据
107
+ * @param removeNull - 是否移除 null
108
+ * @param removeEmptyString - 是否移除空字符串
109
+ * @returns 清理后的数据
110
+ */
111
+ cleanData(data: DataObject, removeNull: boolean = true, removeEmptyString: boolean = true): DataObject {
112
+ const result: DataObject = {};
113
+
114
+ for (const [key, value] of Object.entries(data)) {
115
+ // 跳过 undefined
116
+ if (value === undefined) continue;
117
+
118
+ // 跳过 null(如果配置)
119
+ if (removeNull && value === null) continue;
120
+
121
+ // 跳过空字符串(如果配置)
122
+ if (removeEmptyString && value === '') continue;
123
+
124
+ result[key] = value;
125
+ }
126
+
127
+ return result;
128
+ }
129
+
130
+ /**
131
+ * 合并数据对象(深度合并)
132
+ * @param target - 目标对象
133
+ * @param sources - 源对象(可多个)
134
+ * @returns 合并后的对象
135
+ */
136
+ mergeData(target: DataObject, ...sources: DataObject[]): DataObject {
137
+ const result = { ...target };
138
+
139
+ for (const source of sources) {
140
+ for (const [key, value] of Object.entries(source)) {
141
+ if (value !== undefined) {
142
+ result[key] = value;
143
+ }
144
+ }
145
+ }
146
+
147
+ return result;
148
+ }
149
+
150
+ /**
151
+ * 提取指定字段
152
+ * @param data - 原始数据
153
+ * @param fields - 字段列表
154
+ * @returns 提取后的数据
155
+ */
156
+ pickFields(data: DataObject, fields: string[]): DataObject {
157
+ const result: DataObject = {};
158
+
159
+ for (const field of fields) {
160
+ if (field in data) {
161
+ result[field] = data[field];
162
+ }
163
+ }
164
+
165
+ return result;
166
+ }
167
+
168
+ /**
169
+ * 排除指定字段
170
+ * @param data - 原始数据
171
+ * @param fields - 字段列表
172
+ * @returns 排除后的数据
173
+ */
174
+ omitFields(data: DataObject, fields: string[]): DataObject {
175
+ const result = { ...data };
176
+
177
+ for (const field of fields) {
178
+ delete result[field];
179
+ }
180
+
181
+ return result;
182
+ }
183
+
184
+ /**
185
+ * 重命名字段
186
+ * @param data - 原始数据
187
+ * @param mapping - 字段映射 { oldKey: newKey }
188
+ * @returns 重命名后的数据
189
+ */
190
+ renameFields(data: DataObject, mapping: Record<string, string>): DataObject {
191
+ const result = { ...data };
192
+
193
+ for (const [oldKey, newKey] of Object.entries(mapping)) {
194
+ if (oldKey in result) {
195
+ result[newKey] = result[oldKey];
196
+ delete result[oldKey];
197
+ }
198
+ }
199
+
200
+ return result;
201
+ }
202
+
203
+ /**
204
+ * 转换字段类型
205
+ * @param data - 原始数据
206
+ * @param conversions - 转换规则 { field: 'number' | 'string' | 'boolean' }
207
+ * @returns 转换后的数据
208
+ */
209
+ convertFields(data: DataObject, conversions: Record<string, 'number' | 'string' | 'boolean'>): DataObject {
210
+ const result = { ...data };
211
+
212
+ for (const [field, type] of Object.entries(conversions)) {
213
+ if (field in result && result[field] !== null && result[field] !== undefined) {
214
+ switch (type) {
215
+ case 'number':
216
+ result[field] = Number(result[field]);
217
+ break;
218
+ case 'string':
219
+ result[field] = String(result[field]);
220
+ break;
221
+ case 'boolean':
222
+ result[field] = Boolean(result[field]);
223
+ break;
224
+ }
225
+ }
226
+ }
227
+
228
+ return result;
229
+ }
230
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Befly 类型判断工具
3
+ * 提供各种类型检查和判断功能
4
+ */
5
+
6
+ /**
7
+ * 类型判断
8
+ * @param value - 要判断的值
9
+ * @param type - 期望的类型
10
+ * @returns 是否匹配指定类型
11
+ *
12
+ * @example
13
+ * isType(123, 'number') // true
14
+ * isType('hello', 'string') // true
15
+ * isType([], 'array') // true
16
+ * isType({}, 'object') // true
17
+ * isType(null, 'null') // true
18
+ * isType(undefined, 'undefined') // true
19
+ * isType(NaN, 'nan') // true
20
+ * isType(42, 'integer') // true
21
+ * isType(3.14, 'float') // true
22
+ * isType(10, 'positive') // true
23
+ * isType(-5, 'negative') // true
24
+ * isType(0, 'zero') // true
25
+ * isType('', 'empty') // true
26
+ * isType(null, 'empty') // true
27
+ * isType(true, 'truthy') // true
28
+ * isType(false, 'falsy') // true
29
+ * isType('str', 'primitive') // true
30
+ * isType({}, 'reference') // true
31
+ */
32
+ export const isType = (value: any, type: string): boolean => {
33
+ const actualType = Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
34
+ const expectedType = String(type).toLowerCase();
35
+
36
+ // 语义类型单独处理
37
+ switch (expectedType) {
38
+ case 'function':
39
+ return typeof value === 'function';
40
+ case 'nan':
41
+ return typeof value === 'number' && Number.isNaN(value);
42
+ case 'empty':
43
+ return value === '' || value === null || value === undefined;
44
+ case 'integer':
45
+ return Number.isInteger(value);
46
+ case 'float':
47
+ return typeof value === 'number' && !Number.isInteger(value) && !Number.isNaN(value);
48
+ case 'positive':
49
+ return typeof value === 'number' && value > 0;
50
+ case 'negative':
51
+ return typeof value === 'number' && value < 0;
52
+ case 'zero':
53
+ return value === 0;
54
+ case 'truthy':
55
+ return !!value;
56
+ case 'falsy':
57
+ return !value;
58
+ case 'primitive':
59
+ return value !== Object(value);
60
+ case 'reference':
61
+ return value === Object(value);
62
+ default:
63
+ return actualType === expectedType;
64
+ }
65
+ };
66
+
67
+ /**
68
+ * 判断是否为空对象
69
+ * @param obj - 要判断的值
70
+ * @returns 是否为空对象
71
+ *
72
+ * @example
73
+ * isEmptyObject({}) // true
74
+ * isEmptyObject({ a: 1 }) // false
75
+ * isEmptyObject([]) // false
76
+ * isEmptyObject(null) // false
77
+ */
78
+ export const isEmptyObject = (obj: any): boolean => {
79
+ if (!isType(obj, 'object')) {
80
+ return false;
81
+ }
82
+ return Object.keys(obj).length === 0;
83
+ };
84
+
85
+ /**
86
+ * 判断是否为空数组
87
+ * @param arr - 要判断的值
88
+ * @returns 是否为空数组
89
+ *
90
+ * @example
91
+ * isEmptyArray([]) // true
92
+ * isEmptyArray([1, 2]) // false
93
+ * isEmptyArray({}) // false
94
+ * isEmptyArray(null) // false
95
+ */
96
+ export const isEmptyArray = (arr: any): boolean => {
97
+ if (!isType(arr, 'array')) {
98
+ return false;
99
+ }
100
+ return arr.length === 0;
101
+ };