befly 3.8.30 → 3.8.32

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 (47) hide show
  1. package/README.md +83 -0
  2. package/{config.ts → befly.config.ts} +26 -6
  3. package/checks/checkApp.ts +31 -1
  4. package/hooks/cors.ts +3 -3
  5. package/hooks/parser.ts +3 -3
  6. package/hooks/validator.ts +1 -1
  7. package/lib/cacheHelper.ts +0 -6
  8. package/lib/cipher.ts +2 -1
  9. package/lib/connect.ts +17 -19
  10. package/lib/jwt.ts +1 -1
  11. package/lib/logger.ts +1 -1
  12. package/lib/validator.ts +149 -384
  13. package/loader/loadHooks.ts +4 -3
  14. package/loader/loadPlugins.ts +7 -9
  15. package/main.ts +22 -36
  16. package/package.json +6 -5
  17. package/plugins/cipher.ts +1 -1
  18. package/plugins/config.ts +3 -4
  19. package/plugins/db.ts +4 -5
  20. package/plugins/jwt.ts +3 -2
  21. package/plugins/logger.ts +6 -6
  22. package/plugins/redis.ts +8 -12
  23. package/router/static.ts +3 -6
  24. package/sync/syncAll.ts +7 -12
  25. package/sync/syncApi.ts +4 -3
  26. package/sync/syncDb.ts +6 -5
  27. package/sync/syncDev.ts +9 -8
  28. package/sync/syncMenu.ts +174 -132
  29. package/tests/integration.test.ts +2 -6
  30. package/tests/redisHelper.test.ts +1 -2
  31. package/tests/validator.test.ts +611 -85
  32. package/types/befly.d.ts +7 -0
  33. package/types/cache.d.ts +73 -0
  34. package/types/common.d.ts +1 -37
  35. package/types/database.d.ts +5 -0
  36. package/types/index.ts +5 -5
  37. package/types/plugin.d.ts +1 -4
  38. package/types/redis.d.ts +37 -2
  39. package/types/table.d.ts +6 -44
  40. package/util.ts +283 -0
  41. package/tests/validator-advanced.test.ts +0 -653
  42. package/types/addon.d.ts +0 -50
  43. package/types/crypto.d.ts +0 -23
  44. package/types/jwt.d.ts +0 -99
  45. package/types/logger.d.ts +0 -13
  46. package/types/tool.d.ts +0 -67
  47. package/types/validator.d.ts +0 -43
package/lib/validator.ts CHANGED
@@ -1,462 +1,227 @@
1
1
  /**
2
2
  * 数据验证器 - Befly 项目专用
3
- * 内置 RegexAliases,支持对象格式的字段定义
4
- * 使用正则缓存优化性能
3
+ * 纯静态类设计,简洁易用
5
4
  */
6
5
 
7
- import type { ValidationResult, ValidationError } from '../types/validator';
8
6
  import { RegexAliases, getCompiledRegex } from 'befly-shared/regex';
9
- import type { TableDefinition, FieldDefinition } from 'befly-shared/types';
7
+ import type { TableDefinition, FieldDefinition, ValidateResult, SingleResult } from 'befly-shared/types';
10
8
 
11
9
  /**
12
- * 验证器类(Befly 项目专用)
13
- * 内置 RegexAliases,直接使用 util.ts 中的 parseRule
10
+ * 验证器类
11
+ *
12
+ * @example
13
+ * const result = Validator.validate(data, rules, ['email', 'name']);
14
+ * if (result.failed) {
15
+ * console.log(result.firstError);
16
+ * console.log(result.errors);
17
+ * console.log(result.errorFields);
18
+ * }
19
+ *
20
+ * const single = Validator.single(value, fieldDef);
21
+ * if (!single.error) {
22
+ * console.log(single.value);
23
+ * }
14
24
  */
15
25
  export class Validator {
16
- /** 正则别名映射(内置) */
17
- private readonly regexAliases: Record<string, string> = RegexAliases;
18
-
19
26
  /**
20
- * 验证数据
21
- * @param data - 要验证的数据对象
22
- * @param rules - 验证规则对象
23
- * @param required - 必传字段数组
24
- * @returns 验证结果 { code: 0|1, fields: {} }
27
+ * 验证数据对象
25
28
  */
26
- validate(data: Record<string, any>, rules: TableDefinition, required: string[] = []): ValidationResult {
27
- const result: ValidationResult = {
28
- code: 0,
29
- fields: {}
30
- };
29
+ static validate(data: Record<string, any>, rules: TableDefinition, required: string[] = []): ValidateResult {
30
+ const fieldErrors: Record<string, string> = {};
31
31
 
32
32
  // 参数检查
33
- if (!this.checkParams(data, rules, required, result)) {
34
- return result;
35
- }
36
-
37
- // 检查必传字段
38
- this.checkRequiredFields(data, rules, required, result);
39
-
40
- // 验证所有在规则中定义的字段
41
- this.validateFields(data, rules, required, result);
42
-
43
- return result;
44
- }
45
-
46
- /**
47
- * 检查参数有效性
48
- */
49
- private checkParams(data: any, rules: any, required: any, result: ValidationResult): boolean {
50
33
  if (!data || typeof data !== 'object' || Array.isArray(data)) {
51
- result.code = 1;
52
- result.fields.error = '数据必须是对象格式';
53
- return false;
34
+ return this.buildResult({ _error: '数据必须是对象格式' });
54
35
  }
55
-
56
36
  if (!rules || typeof rules !== 'object') {
57
- result.code = 1;
58
- result.fields.error = '验证规则必须是对象格式';
59
- return false;
37
+ return this.buildResult({ _error: '验证规则必须是对象格式' });
60
38
  }
61
39
 
62
- if (!Array.isArray(required)) {
63
- result.code = 1;
64
- result.fields.error = '必传字段必须是数组格式';
65
- return false;
40
+ // 检查必填字段
41
+ for (const field of required) {
42
+ const value = data[field];
43
+ if (value === undefined || value === null || value === '') {
44
+ const label = rules[field]?.name || field;
45
+ fieldErrors[field] = `${label}为必填项`;
46
+ }
66
47
  }
67
48
 
68
- return true;
69
- }
49
+ // 验证有值的字段
50
+ for (const [field, rule] of Object.entries(rules)) {
51
+ if (fieldErrors[field]) continue;
52
+ if (!(field in data) && !required.includes(field)) continue;
70
53
 
71
- /**
72
- * 检查必传字段
73
- */
74
- private checkRequiredFields(data: Record<string, any>, rules: TableDefinition, required: string[], result: ValidationResult): void {
75
- for (const fieldName of required) {
76
- const value = data[fieldName];
77
- if (!(fieldName in data) || value === undefined || value === null || value === '') {
78
- result.code = 1;
79
- const fieldDef = rules[fieldName];
80
- const fieldLabel = fieldDef?.name || fieldName;
81
- result.fields[fieldName] = `${fieldLabel}(${fieldName})为必填项`;
82
- }
54
+ const error = this.checkField(data[field], rule, field);
55
+ if (error) fieldErrors[field] = error;
83
56
  }
57
+
58
+ return this.buildResult(fieldErrors);
84
59
  }
85
60
 
86
61
  /**
87
- * 验证所有字段
62
+ * 验证单个值(带类型转换)
88
63
  */
89
- private validateFields(data: Record<string, any>, rules: TableDefinition, required: string[], result: ValidationResult): void {
90
- for (const [fieldName, rule] of Object.entries(rules)) {
91
- // 如果字段不存在且不是必传字段,跳过验证
92
- if (!(fieldName in data) && !required.includes(fieldName)) {
93
- continue;
94
- }
95
-
96
- // 如果必传验证已经失败,跳过后续验证
97
- if (result.fields[fieldName]) {
98
- continue;
99
- }
64
+ static single(value: any, fieldDef: FieldDefinition): SingleResult {
65
+ const { type, default: defaultValue } = fieldDef;
100
66
 
101
- const value = data[fieldName];
102
- const error = this.validateFieldValue(value, rules[fieldName], fieldName);
103
-
104
- if (error) {
105
- result.code = 1;
106
- result.fields[fieldName] = error;
107
- }
67
+ // 处理空值
68
+ if (value === undefined || value === null || value === '') {
69
+ return { value: this.defaultFor(type, defaultValue), error: null };
108
70
  }
109
- }
110
71
 
111
- /**
112
- * 解析 regex 别名
113
- */
114
- private resolveRegexAlias(regex: string | null): string | null {
115
- if (!regex || typeof regex !== 'string') {
116
- return regex;
72
+ // 类型转换
73
+ const converted = this.convert(value, type);
74
+ if (converted.error) {
75
+ return { value: null, error: converted.error };
117
76
  }
118
77
 
119
- if (regex.startsWith('@')) {
120
- const aliasName = regex.substring(1);
121
- const resolvedRegex = this.regexAliases[aliasName];
122
- if (resolvedRegex) {
123
- return resolvedRegex;
124
- }
125
- return regex;
78
+ // 规则验证
79
+ const error = this.checkRule(converted.value, fieldDef);
80
+ if (error) {
81
+ return { value: null, error: error };
126
82
  }
127
83
 
128
- return regex;
84
+ return { value: converted.value, error: null };
129
85
  }
130
86
 
131
- /**
132
- * 验证单个字段的值
133
- */
134
- private validateFieldValue(value: any, fieldDef: FieldDefinition, fieldName: string): ValidationError {
135
- let { name, type, min, max, regexp } = fieldDef;
87
+ // ========== 私有方法 ==========
136
88
 
137
- regexp = this.resolveRegexAlias(regexp);
89
+ /** 构建结果对象 */
90
+ private static buildResult(fieldErrors: Record<string, string>): ValidateResult {
91
+ const errors = Object.values(fieldErrors);
92
+ const errorFields = Object.keys(fieldErrors);
93
+ const failed = errors.length > 0;
138
94
 
139
- switch (type.toLowerCase()) {
140
- case 'number':
141
- return this.validateNumber(value, name, min, max, regexp, fieldName);
142
- case 'string':
143
- case 'text':
144
- return this.validateString(value, name, min, max, regexp, fieldName);
145
- case 'array_string':
146
- case 'array_text':
147
- return this.validateArray(value, name, min, max, regexp, fieldName);
148
- default:
149
- return `字段 ${fieldName} 的类型 ${type} 不支持`;
150
- }
95
+ return {
96
+ code: failed ? 1 : 0,
97
+ failed: failed,
98
+ firstError: failed ? errors[0] : null,
99
+ errors: errors,
100
+ errorFields: errorFields,
101
+ fieldErrors: fieldErrors
102
+ };
151
103
  }
152
104
 
153
- /**
154
- * 验证数字类型
155
- */
156
- private validateNumber(value: any, name: string, min: number | null, max: number | null, spec: string | null, fieldName: string): ValidationError {
157
- try {
158
- // 允许数字类型的字符串
159
- let numValue = value;
160
- if (typeof value === 'string') {
161
- numValue = Number(value);
162
- if (Number.isNaN(numValue) || !isFinite(numValue)) {
163
- return `${name}(${fieldName})必须是数字`;
164
- }
165
- } else if (typeof numValue !== 'number' || Number.isNaN(numValue) || !isFinite(numValue)) {
166
- return `${name}(${fieldName})必须是数字`;
167
- }
168
-
169
- if (min !== null && numValue < min) {
170
- return `${name}(${fieldName})不能小于${min}`;
171
- }
172
-
173
- if (max !== null && max > 0 && numValue > max) {
174
- return `${name}(${fieldName})不能大于${max}`;
175
- }
176
-
177
- if (spec && spec.trim() !== '') {
178
- try {
179
- const regExp = getCompiledRegex(spec);
180
- if (!regExp.test(String(numValue))) {
181
- return `${name}(${fieldName})格式不正确`;
182
- }
183
- } catch (error: any) {
184
- return `${name}(${fieldName})的正则表达式格式错误`;
185
- }
186
- }
105
+ /** 验证单个字段 */
106
+ private static checkField(value: any, fieldDef: FieldDefinition, fieldName: string): string | null {
107
+ const label = fieldDef.name || fieldName;
187
108
 
188
- return null;
189
- } catch (error: any) {
190
- return `${name}(${fieldName})验证出错: ${error.message}`;
109
+ const converted = this.convert(value, fieldDef.type);
110
+ if (converted.error) {
111
+ return `${label}${converted.error}`;
191
112
  }
192
- }
193
113
 
194
- /**
195
- * 验证字符串类型
196
- */
197
- private validateString(value: any, name: string, min: number | null, max: number | null, spec: string | null, fieldName: string): ValidationError {
198
- try {
199
- if (typeof value !== 'string') {
200
- return `${name}(${fieldName})必须是字符串`;
201
- }
202
-
203
- if (min !== null && value.length < min) {
204
- return `${name}(${fieldName})长度不能少于${min}个字符`;
205
- }
206
-
207
- if (max !== null && max > 0 && value.length > max) {
208
- return `${name}(${fieldName})长度不能超过${max}个字符`;
209
- }
210
-
211
- if (spec && spec.trim() !== '') {
212
- try {
213
- const regExp = getCompiledRegex(spec);
214
- if (!regExp.test(value)) {
215
- return `${name}(${fieldName})格式不正确`;
216
- }
217
- } catch (error: any) {
218
- return `${name}(${fieldName})的正则表达式格式错误`;
219
- }
220
- }
221
-
222
- return null;
223
- } catch (error: any) {
224
- return `${name}(${fieldName})验证出错: ${error.message}`;
225
- }
114
+ const error = this.checkRule(converted.value, fieldDef);
115
+ return error ? `${label}${error}` : null;
226
116
  }
227
117
 
228
- /**
229
- * 验证数组类型
230
- */
231
- private validateArray(value: any, name: string, min: number | null, max: number | null, spec: string | null, fieldName: string): ValidationError {
232
- try {
233
- if (!Array.isArray(value)) {
234
- return `${name}(${fieldName})必须是数组`;
235
- }
236
-
237
- if (min !== null && value.length < min) {
238
- return `${name}(${fieldName})至少需要${min}个元素`;
239
- }
240
-
241
- if (max !== null && max > 0 && value.length > max) {
242
- return `${name}(${fieldName})最多只能有${max}个元素`;
243
- }
244
-
245
- if (spec && spec.trim() !== '') {
246
- try {
247
- const regExp = getCompiledRegex(spec);
248
- for (const item of value) {
249
- if (!regExp.test(String(item))) {
250
- return `${name}(${fieldName})中的元素"${item}"格式不正确`;
251
- }
252
- }
253
- } catch (error: any) {
254
- return `${name}(${fieldName})的正则表达式格式错误`;
118
+ /** 类型转换 */
119
+ private static convert(value: any, type: string): { value: any; error: string | null } {
120
+ switch (type.toLowerCase()) {
121
+ case 'number':
122
+ if (typeof value === 'number') {
123
+ return Number.isNaN(value) || !isFinite(value) ? { value: null, error: '必须是有效数字' } : { value: value, error: null };
255
124
  }
256
- }
257
-
258
- return null;
259
- } catch (error: any) {
260
- return `${name}(${fieldName})验证出错: ${error.message}`;
261
- }
262
- }
125
+ if (typeof value === 'string') {
126
+ const num = Number(value);
127
+ return Number.isNaN(num) || !isFinite(num) ? { value: null, error: '必须是数字' } : { value: num, error: null };
128
+ }
129
+ return { value: null, error: '必须是数字' };
263
130
 
264
- /**
265
- * 验证单个值(支持对象格式字段定义)
266
- */
267
- validateSingleValue(value: any, fieldDef: FieldDefinition): { valid: boolean; value: any; errors: string[] } {
268
- let { name, type, min, max, regexp, default: defaultValue } = fieldDef;
131
+ case 'string':
132
+ case 'text':
133
+ return typeof value === 'string' ? { value: value, error: null } : { value: null, error: '必须是字符串' };
269
134
 
270
- regexp = this.resolveRegexAlias(regexp);
135
+ case 'array_string':
136
+ case 'array_text':
137
+ return Array.isArray(value) ? { value: value, error: null } : { value: null, error: '必须是数组' };
271
138
 
272
- // 处理 undefined/null 值,使用默认值
273
- if (value === undefined || value === null) {
274
- if (defaultValue !== null) {
275
- if ((type === 'array_string' || type === 'array_text') && typeof defaultValue === 'string') {
276
- if (defaultValue === '[]') {
277
- return { valid: true, value: [], errors: [] };
278
- }
279
- try {
280
- const parsedArray = JSON.parse(defaultValue);
281
- if (Array.isArray(parsedArray)) {
282
- return { valid: true, value: parsedArray, errors: [] };
283
- }
284
- } catch {
285
- return { valid: true, value: [], errors: [] };
286
- }
287
- }
288
- // 数字类型默认值转换
289
- if (type === 'number' && typeof defaultValue === 'string') {
290
- const numValue = Number(defaultValue);
291
- if (!isNaN(numValue)) {
292
- return { valid: true, value: numValue, errors: [] };
293
- }
294
- }
295
- return { valid: true, value: defaultValue, errors: [] };
296
- }
297
- if (type === 'number') {
298
- return { valid: true, value: 0, errors: [] };
299
- } else if (type === 'array_string' || type === 'array_text') {
300
- return { valid: true, value: [], errors: [] };
301
- } else if (type === 'string' || type === 'text') {
302
- return { valid: true, value: '', errors: [] };
303
- }
139
+ default:
140
+ return { value: value, error: null };
304
141
  }
142
+ }
305
143
 
306
- const errors: string[] = [];
144
+ /** 规则验证 */
145
+ private static checkRule(value: any, fieldDef: FieldDefinition): string | null {
146
+ const { type, min, max, regexp } = fieldDef;
147
+ const regex = this.resolveRegex(regexp);
307
148
 
308
- // 类型转换
309
- let convertedValue = value;
310
- if (type === 'number' && typeof value === 'string') {
311
- convertedValue = Number(value);
312
- if (isNaN(convertedValue)) {
313
- errors.push(`${name || '值'}必须是有效的数字`);
314
- return { valid: false, value: null, errors };
315
- }
316
- }
317
-
318
- // 类型验证
319
149
  switch (type.toLowerCase()) {
320
150
  case 'number':
321
- if (typeof convertedValue !== 'number' || Number.isNaN(convertedValue)) {
322
- errors.push(`${name || '值'}必须是数字`);
323
- }
324
- if (min !== null && convertedValue < min) {
325
- errors.push(`${name || '值'}不能小于${min}`);
326
- }
327
- if (max !== null && max > 0 && convertedValue > max) {
328
- errors.push(`${name || '值'}不能大于${max}`);
329
- }
330
- if (regexp && regexp.trim() !== '') {
331
- try {
332
- const regExp = getCompiledRegex(regexp);
333
- if (!regExp.test(String(convertedValue))) {
334
- errors.push(`${name || '值'}格式不正确`);
335
- }
336
- } catch (e: any) {
337
- errors.push(`${name || '值'}的正则表达式格式错误: ${e.message}`);
338
- }
339
- }
151
+ if (min !== null && value < min) return `不能小于${min}`;
152
+ if (max !== null && max > 0 && value > max) return `不能大于${max}`;
153
+ if (regex && !this.testRegex(regex, String(value))) return '格式不正确';
340
154
  break;
341
155
 
342
156
  case 'string':
343
157
  case 'text':
344
- if (typeof convertedValue !== 'string') {
345
- errors.push(`${name || '值'}必须是字符串`);
346
- }
347
- if (min !== null && convertedValue.length < min) {
348
- errors.push(`${name || '值'}长度不能少于${min}个字符`);
349
- }
350
- if (max !== null && max > 0 && convertedValue.length > max) {
351
- errors.push(`${name || '值'}长度不能超过${max}个字符`);
352
- }
353
- if (regexp && regexp.trim() !== '') {
354
- try {
355
- const regExp = getCompiledRegex(regexp);
356
- if (!regExp.test(convertedValue)) {
357
- errors.push(`${name || '值'}格式不正确`);
358
- }
359
- } catch {
360
- errors.push(`${name || '值'}的正则表达式格式错误`);
361
- }
362
- }
158
+ if (min !== null && value.length < min) return `长度不能少于${min}个字符`;
159
+ if (max !== null && max > 0 && value.length > max) return `长度不能超过${max}个字符`;
160
+ if (regex && !this.testRegex(regex, value)) return '格式不正确';
363
161
  break;
364
162
 
365
163
  case 'array_string':
366
164
  case 'array_text':
367
- if (!Array.isArray(convertedValue)) {
368
- errors.push(`${name || '值'}必须是数组`);
369
- }
370
- if (min !== null && convertedValue.length < min) {
371
- errors.push(`${name || ''}元素数量不能少于${min}个`);
372
- }
373
- if (max !== null && max > 0 && convertedValue.length > max) {
374
- errors.push(`${name || '值'}元素数量不能超过${max}个`);
375
- }
376
- if (regexp && regexp.trim() !== '') {
377
- try {
378
- const regExp = getCompiledRegex(regexp);
379
- for (const item of convertedValue) {
380
- if (!regExp.test(String(item))) {
381
- errors.push(`${name || '值'}的元素格式不正确`);
382
- break;
383
- }
384
- }
385
- } catch {
386
- errors.push(`${name || '值'}的正则表达式格式错误`);
165
+ if (min !== null && value.length < min) return `至少需要${min}个元素`;
166
+ if (max !== null && max > 0 && value.length > max) return `最多只能有${max}个元素`;
167
+ if (regex) {
168
+ for (const item of value) {
169
+ if (!this.testRegex(regex, String(item))) return '元素格式不正确';
387
170
  }
388
171
  }
389
172
  break;
390
173
  }
391
-
392
- return {
393
- valid: errors.length === 0,
394
- value: errors.length === 0 ? convertedValue : null,
395
- errors
396
- };
174
+ return null;
397
175
  }
398
176
 
399
- /**
400
- * 静态方法:快速验证
401
- */
402
- static validate(data: Record<string, any>, rules: TableDefinition, required?: string[]): ValidationResult;
403
- static validate(value: any, fieldDef: FieldDefinition): { valid: boolean; value: any; errors: string[] };
404
- static validate(dataOrValue: any, rulesOrFieldDef: any, required?: string[]): any {
405
- const validator = new Validator();
406
-
407
- if (rulesOrFieldDef && 'type' in rulesOrFieldDef) {
408
- return validator.validateSingleValue(dataOrValue, rulesOrFieldDef);
177
+ /** 解析正则别名 */
178
+ private static resolveRegex(regexp: string | null): string | null {
179
+ if (!regexp) return null;
180
+ if (regexp.startsWith('@')) {
181
+ return RegexAliases[regexp.substring(1)] || regexp;
409
182
  }
410
-
411
- return validator.validate(dataOrValue, rulesOrFieldDef, required || []);
183
+ return regexp;
412
184
  }
413
185
 
414
- /**
415
- * 检查验证是否通过
416
- */
417
- static isPassed(result: ValidationResult | { valid: boolean; value: any; errors: string[] }): boolean {
418
- if ('valid' in result) {
419
- return result.valid === true;
186
+ /** 测试正则 */
187
+ private static testRegex(pattern: string, value: string): boolean {
188
+ try {
189
+ return getCompiledRegex(pattern).test(value);
190
+ } catch {
191
+ return false;
420
192
  }
421
- return result.code === 0;
422
193
  }
423
194
 
424
- /**
425
- * 检查验证是否失败
426
- */
427
- static isFailed(result: ValidationResult): boolean {
428
- return result.code === 1;
429
- }
430
-
431
- /**
432
- * 获取第一个错误信息
433
- */
434
- static getFirstError(result: ValidationResult | { valid: boolean; value: any; errors: string[] }): string | null {
435
- if ('valid' in result) {
436
- return result.errors.length > 0 ? result.errors[0] : null;
195
+ /** 获取默认值 */
196
+ private static defaultFor(type: string, defaultValue: any): any {
197
+ if (defaultValue !== null && defaultValue !== undefined) {
198
+ // 数组默认值
199
+ if ((type === 'array_string' || type === 'array_text') && typeof defaultValue === 'string') {
200
+ if (defaultValue === '[]') return [];
201
+ try {
202
+ const parsed = JSON.parse(defaultValue);
203
+ return Array.isArray(parsed) ? parsed : [];
204
+ } catch {
205
+ return [];
206
+ }
207
+ }
208
+ // 数字默认值
209
+ if (type === 'number' && typeof defaultValue === 'string') {
210
+ const num = Number(defaultValue);
211
+ return isNaN(num) ? 0 : num;
212
+ }
213
+ return defaultValue;
437
214
  }
438
- if (result.code === 0) return null;
439
- if (!result.fields) return null;
440
- const errors = Object.values(result.fields);
441
- return errors.length > 0 ? errors[0] : null;
442
- }
443
215
 
444
- /**
445
- * 获取所有错误信息
446
- */
447
- static getAllErrors(result: ValidationResult | { valid: boolean; value: any; errors: string[] }): string[] {
448
- if ('valid' in result) {
449
- return result.errors;
216
+ // 类型默认值
217
+ switch (type.toLowerCase()) {
218
+ case 'number':
219
+ return 0;
220
+ case 'array_string':
221
+ case 'array_text':
222
+ return [];
223
+ default:
224
+ return '';
450
225
  }
451
- if (result.code === 0) return [];
452
- if (!result.fields) return [];
453
- return Object.values(result.fields);
454
- }
455
-
456
- /**
457
- * 获取错误字段列表
458
- */
459
- static getErrorFields(result: ValidationResult): string[] {
460
- return result.code === 0 ? [] : Object.keys(result.fields);
461
226
  }
462
227
  }
@@ -7,17 +7,18 @@
7
7
  import { Logger } from '../lib/logger.js';
8
8
  import { coreHookDir } from '../paths.js';
9
9
  import { scanModules } from '../util.js';
10
+ import { beflyConfig } from '../befly.config.js';
10
11
 
11
12
  // 类型导入
12
13
  import type { Hook } from '../types/hook.js';
13
14
 
14
- export async function loadHooks(pluginsConfig: Record<string, any> | undefined, hooks: Hook[]): Promise<void> {
15
+ export async function loadHooks(hooks: Hook[]): Promise<void> {
15
16
  try {
16
17
  // 1. 扫描核心钩子
17
- const coreHooks = await scanModules<Hook>(coreHookDir, 'core', '钩子', pluginsConfig);
18
+ const coreHooks = await scanModules<Hook>(coreHookDir, 'core', '钩子');
18
19
 
19
20
  // 2. 过滤禁用的钩子
20
- const disableHooks = (pluginsConfig as any)?.disableHooks || [];
21
+ const disableHooks = beflyConfig.disableHooks || [];
21
22
  const enabledHooks = coreHooks.filter((hook) => !disableHooks.includes(hook.name));
22
23
 
23
24
  if (disableHooks.length > 0) {