schema-dsl 1.0.9 → 1.1.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 (47) hide show
  1. package/CHANGELOG.md +325 -2
  2. package/README.md +419 -189
  3. package/STATUS.md +65 -3
  4. package/docs/FEATURE-INDEX.md +1 -1
  5. package/docs/best-practices.md +3 -3
  6. package/docs/cache-manager.md +1 -1
  7. package/docs/conditional-api.md +1278 -0
  8. package/docs/dsl-syntax.md +1 -1
  9. package/docs/dynamic-locale.md +2 -2
  10. package/docs/error-handling.md +2 -2
  11. package/docs/export-guide.md +2 -2
  12. package/docs/export-limitations.md +3 -3
  13. package/docs/faq.md +6 -6
  14. package/docs/frontend-i18n-guide.md +1 -1
  15. package/docs/mongodb-exporter.md +3 -3
  16. package/docs/multi-type-support.md +12 -2
  17. package/docs/mysql-exporter.md +1 -1
  18. package/docs/plugin-system.md +4 -4
  19. package/docs/postgresql-exporter.md +1 -1
  20. package/docs/quick-start.md +4 -4
  21. package/docs/troubleshooting.md +2 -2
  22. package/docs/type-reference.md +5 -5
  23. package/docs/typescript-guide.md +5 -6
  24. package/docs/union-type-guide.md +147 -0
  25. package/docs/union-types.md +277 -0
  26. package/docs/validate-async.md +1 -1
  27. package/examples/array-dsl-example.js +1 -1
  28. package/examples/conditional-example.js +288 -0
  29. package/examples/conditional-non-object.js +129 -0
  30. package/examples/conditional-validate-example.js +321 -0
  31. package/examples/i18n-error.examples.js +181 -0
  32. package/examples/union-type-example.js +127 -0
  33. package/examples/union-types-example.js +77 -0
  34. package/index.d.ts +655 -7
  35. package/index.js +54 -3
  36. package/lib/adapters/DslAdapter.js +14 -5
  37. package/lib/core/ConditionalBuilder.js +503 -0
  38. package/lib/core/DslBuilder.js +113 -0
  39. package/lib/core/Locale.js +13 -8
  40. package/lib/core/Validator.js +250 -2
  41. package/lib/errors/I18nError.js +222 -0
  42. package/lib/locales/en-US.js +39 -0
  43. package/lib/locales/es-ES.js +4 -0
  44. package/lib/locales/fr-FR.js +4 -0
  45. package/lib/locales/ja-JP.js +9 -0
  46. package/lib/locales/zh-CN.js +39 -0
  47. package/package.json +3 -1
@@ -0,0 +1,129 @@
1
+ /**
2
+ * ConditionalBuilder 非对象类型示例
3
+ *
4
+ * 展示如何直接验证字符串、数组、布尔值等非对象类型
5
+ */
6
+
7
+ const { dsl, validate } = require('../index');
8
+
9
+ console.log('========================================');
10
+ console.log('ConditionalBuilder - 非对象类型示例');
11
+ console.log('========================================\n');
12
+
13
+ // ============================================
14
+ // 示例1:直接验证字符串
15
+ // ============================================
16
+ console.log('【示例1】直接验证字符串');
17
+ console.log('----------------------------');
18
+
19
+ const stringSchema = dsl.if((data) => typeof data === 'string' && data.includes('@'))
20
+ .then('email!')
21
+ .else('string:1-50');
22
+
23
+ const r1 = validate(stringSchema, 'test@example.com');
24
+ console.log('✅ 邮箱格式:', r1.valid ? '验证通过' : '验证失败');
25
+
26
+ const r2 = validate(stringSchema, 'just a text');
27
+ console.log('✅ 普通文本:', r2.valid ? '验证通过' : '验证失败');
28
+
29
+ // ============================================
30
+ // 示例2:直接验证数组
31
+ // ============================================
32
+ console.log('\n【示例2】直接验证数组');
33
+ console.log('----------------------------');
34
+
35
+ const arraySchema = dsl.if((data) => Array.isArray(data) && data.length > 5)
36
+ .message('数组最多5个元素');
37
+
38
+ const r3 = validate(arraySchema, [1, 2, 3]);
39
+ console.log('✅ 3个元素:', r3.valid ? '验证通过' : '验证失败');
40
+
41
+ const r4 = validate(arraySchema, [1, 2, 3, 4, 5, 6]);
42
+ console.log('❌ 6个元素:', r4.valid ? '验证通过' : '验证失败');
43
+ if (!r4.valid) {
44
+ console.log(' 错误:', r4.errors[0].message);
45
+ }
46
+
47
+ // ============================================
48
+ // 示例3:直接验证数字
49
+ // ============================================
50
+ console.log('\n【示例3】直接验证数字');
51
+ console.log('----------------------------');
52
+
53
+ const numberSchema = dsl.if((data) => typeof data === 'number' && data < 0)
54
+ .message('不允许负数')
55
+ .else(null); // 不需要额外验证
56
+
57
+ const r5 = validate(numberSchema, 10);
58
+ console.log('✅ 正数:', r5.valid ? '验证通过' : '验证失败');
59
+
60
+ const r6 = validate(numberSchema, -5);
61
+ console.log('❌ 负数:', r6.valid ? '验证通过' : '验证失败');
62
+ if (!r6.valid) {
63
+ console.log(' 错误:', r6.errors[0].message);
64
+ }
65
+
66
+ // ============================================
67
+ // 示例4:字符串类型判断(邮箱或手机号)
68
+ // ============================================
69
+ console.log('\n【示例4】自动识别邮箱或手机号');
70
+ console.log('----------------------------');
71
+
72
+ const contactSchema = dsl.if((data) => typeof data === 'string' && data.includes('@'))
73
+ .then('email!')
74
+ .else('string:11!');
75
+
76
+ const r7 = validate(contactSchema, 'user@example.com');
77
+ console.log('✅ 邮箱:', r7.valid ? '验证通过' : '验证失败');
78
+
79
+ const r8 = validate(contactSchema, '13800138000');
80
+ console.log('✅ 手机号:', r8.valid ? '验证通过' : '验证失败');
81
+
82
+ const r9 = validate(contactSchema, 'invalid');
83
+ console.log('❌ 无效输入:', r9.valid ? '验证通过' : '验证失败');
84
+ if (!r9.valid) {
85
+ console.log(' 错误:', r9.errors[0].message);
86
+ }
87
+
88
+ // ============================================
89
+ // 示例5:复杂条件组合
90
+ // ============================================
91
+ console.log('\n【示例5】字符串长度 + 内容组合判断');
92
+ console.log('----------------------------');
93
+
94
+ const complexSchema = dsl.if((data) => typeof data === 'string' && data.length > 20)
95
+ .and((data) => data.includes('@'))
96
+ .then('email!')
97
+ .else('string:1-50');
98
+
99
+ const r10 = validate(complexSchema, 'short');
100
+ console.log('✅ 短字符串:', r10.valid ? '验证通过' : '验证失败');
101
+
102
+ const r11 = validate(complexSchema, 'this-is-a-long-email@example.com');
103
+ console.log('✅ 长邮箱:', r11.valid ? '验证通过' : '验证失败');
104
+
105
+ const r12 = validate(complexSchema, 'this is a very long string without at symbol');
106
+ console.log('✅ 长文本(无@):', r12.valid ? '验证通过' : '验证失败');
107
+
108
+ // ============================================
109
+ // 示例6:边界值处理
110
+ // ============================================
111
+ console.log('\n【示例6】边界值处理');
112
+ console.log('----------------------------');
113
+
114
+ const boundarySchema = dsl.if((data) => data === null || data === undefined || data === '')
115
+ .message('值不能为空');
116
+
117
+ const r13 = validate(boundarySchema, 'valid value');
118
+ console.log('✅ 有效值:', r13.valid ? '验证通过' : '验证失败');
119
+
120
+ const r14 = validate(boundarySchema, '');
121
+ console.log('❌ 空字符串:', r14.valid ? '验证通过' : '验证失败');
122
+ if (!r14.valid) {
123
+ console.log(' 错误:', r14.errors[0].message);
124
+ }
125
+
126
+ console.log('\n========================================');
127
+ console.log('示例运行完成!');
128
+ console.log('========================================');
129
+
@@ -0,0 +1,321 @@
1
+ /**
2
+ * ConditionalBuilder 快捷验证方法示例
3
+ *
4
+ * 展示 .validate() 和 .check() 方法的使用
5
+ */
6
+
7
+ const { dsl } = require('../index');
8
+
9
+ console.log('========================================');
10
+ console.log('ConditionalBuilder - 快捷验证方法示例');
11
+ console.log('========================================\n');
12
+
13
+ // ============================================
14
+ // 示例1:一行代码验证
15
+ // ============================================
16
+ console.log('【示例1】一行代码验证');
17
+ console.log('----------------------------');
18
+
19
+ const result1 = dsl.if(d => d.age < 18)
20
+ .message('未成年用户不能注册')
21
+ .validate({ age: 16 });
22
+
23
+ console.log('验证未成年用户:', result1.valid ? '✅ 通过' : '❌ 失败');
24
+ if (!result1.valid) {
25
+ console.log('错误:', result1.errors[0].message);
26
+ }
27
+
28
+ const result2 = dsl.if(d => d.age < 18)
29
+ .message('未成年用户不能注册')
30
+ .validate({ age: 20 });
31
+
32
+ console.log('验证成年用户:', result2.valid ? '✅ 通过' : '❌ 失败');
33
+
34
+ // ============================================
35
+ // 示例2:复用验证器
36
+ // ============================================
37
+ console.log('\n【示例2】复用验证器');
38
+ console.log('----------------------------');
39
+
40
+ const ageValidator = dsl.if(d => d.age < 18).message('未成年用户不能注册');
41
+
42
+ const users = [
43
+ { name: '张三', age: 16 },
44
+ { name: '李四', age: 20 },
45
+ { name: '王五', age: 17 },
46
+ { name: '赵六', age: 25 }
47
+ ];
48
+
49
+ users.forEach(user => {
50
+ const result = ageValidator.validate(user);
51
+ console.log(`${user.name}(${user.age}岁):`, result.valid ? '✅ 可以注册' : '❌ 不能注册');
52
+ });
53
+
54
+ // ============================================
55
+ // 示例3:.check() 快速判断
56
+ // ============================================
57
+ console.log('\n【示例3】.check() 快速判断');
58
+ console.log('----------------------------');
59
+
60
+ const canRegister = dsl.if(d => d.age < 18)
61
+ .or(d => d.status === 'blocked')
62
+ .message('不允许注册');
63
+
64
+ const testUsers = [
65
+ { name: '用户A', age: 16, status: 'active' },
66
+ { name: '用户B', age: 20, status: 'blocked' },
67
+ { name: '用户C', age: 20, status: 'active' }
68
+ ];
69
+
70
+ testUsers.forEach(user => {
71
+ const isValid = canRegister.check(user);
72
+ console.log(`${user.name}:`, isValid ? '✅ 允许注册' : '❌ 禁止注册');
73
+ });
74
+
75
+ // ============================================
76
+ // 示例4:then/else 动态验证
77
+ // ============================================
78
+ console.log('\n【示例4】then/else 动态验证');
79
+ console.log('----------------------------');
80
+
81
+ const emailValidator = dsl.if(d => d.userType === 'admin')
82
+ .then('email!') // 管理员必填
83
+ .else('email'); // 普通用户可选
84
+
85
+ // 管理员有邮箱
86
+ const r1 = emailValidator.validate({
87
+ userType: 'admin',
88
+ email: 'admin@example.com'
89
+ });
90
+ console.log('管理员有邮箱:', r1.valid ? '✅ 通过' : '❌ 失败');
91
+
92
+ // 管理员无邮箱
93
+ const r2 = emailValidator.validate({
94
+ userType: 'admin',
95
+ email: ''
96
+ });
97
+ console.log('管理员无邮箱:', r2.valid ? '✅ 通过' : '❌ 失败');
98
+
99
+ // 普通用户无邮箱
100
+ const r3 = emailValidator.validate({
101
+ userType: 'user',
102
+ email: ''
103
+ });
104
+ console.log('普通用户无邮箱:', r3.valid ? '✅ 通过' : '❌ 失败');
105
+
106
+ // ============================================
107
+ // 示例5:非对象类型验证
108
+ // ============================================
109
+ console.log('\n【示例5】非对象类型验证');
110
+ console.log('----------------------------');
111
+
112
+ // 验证字符串
113
+ const stringValidator = dsl.if(d => typeof d === 'string' && d.includes('@'))
114
+ .then('email!')
115
+ .else('string:1-50');
116
+
117
+ const r4 = stringValidator.validate('test@example.com');
118
+ console.log('邮箱格式:', r4.valid ? '✅ 通过' : '❌ 失败');
119
+
120
+ const r5 = stringValidator.validate('just a text');
121
+ console.log('普通文本:', r5.valid ? '✅ 通过' : '❌ 失败');
122
+
123
+ // 验证数组
124
+ const arrayValidator = dsl.if(d => Array.isArray(d) && d.length > 5)
125
+ .message('数组最多5个元素');
126
+
127
+ const r6 = arrayValidator.validate([1, 2, 3]);
128
+ console.log('3个元素:', r6.valid ? '✅ 通过' : '❌ 失败');
129
+
130
+ const r7 = arrayValidator.validate([1, 2, 3, 4, 5, 6]);
131
+ console.log('6个元素:', r7.valid ? '✅ 通过' : '❌ 失败');
132
+ if (!r7.valid) {
133
+ console.log('错误:', r7.errors[0].message);
134
+ }
135
+
136
+ // ============================================
137
+ // 示例6:多语言支持
138
+ // ============================================
139
+ console.log('\n【示例6】多语言支持');
140
+ console.log('----------------------------');
141
+
142
+ const i18nValidator = dsl.if(d => d.age < 18)
143
+ .message('conditional.underAge');
144
+
145
+ // 中文
146
+ const r8 = i18nValidator.validate({ age: 16 }, { locale: 'zh-CN' });
147
+ console.log('中文:', r8.valid ? '✅ 通过' : '❌ 失败');
148
+ if (!r8.valid) {
149
+ console.log('错误:', r8.errors[0].message);
150
+ }
151
+
152
+ // 英文
153
+ const r9 = i18nValidator.validate({ age: 16 }, { locale: 'en-US' });
154
+ console.log('英文:', r9.valid ? '✅ 通过' : '❌ 失败');
155
+ if (!r9.valid) {
156
+ console.log('错误:', r9.errors[0].message);
157
+ }
158
+
159
+ // ============================================
160
+ // 示例7:实际业务场景
161
+ // ============================================
162
+ console.log('\n【示例7】实际业务场景 - 用户注册');
163
+ console.log('----------------------------');
164
+
165
+ // 创建多个验证器
166
+ const validators = {
167
+ age: dsl.if(d => d.age < 18)
168
+ .message('未成年用户不能注册'),
169
+
170
+ email: dsl.if(d => d.userType === 'admin')
171
+ .then('email!')
172
+ .else('email'),
173
+
174
+ phone: dsl.if(d => d.userType === 'vip')
175
+ .then('string:11!')
176
+ .else(null)
177
+ };
178
+
179
+ // 验证用户
180
+ function validateUser(userData) {
181
+ console.log(`\n验证用户: ${userData.username}`);
182
+
183
+ // 年龄检查
184
+ if (!validators.age.check(userData)) {
185
+ console.log('❌ 年龄验证失败');
186
+ return false;
187
+ }
188
+
189
+ // 邮箱检查
190
+ const emailResult = validators.email.validate(userData);
191
+ if (!emailResult.valid) {
192
+ console.log('❌ 邮箱验证失败:', emailResult.errors[0].message);
193
+ return false;
194
+ }
195
+
196
+ // 手机号检查
197
+ const phoneResult = validators.phone.validate(userData);
198
+ if (!phoneResult.valid) {
199
+ console.log('❌ 手机号验证失败:', phoneResult.errors[0].message);
200
+ return false;
201
+ }
202
+
203
+ console.log('✅ 所有验证通过');
204
+ return true;
205
+ }
206
+
207
+ // 测试数据
208
+ const userData1 = {
209
+ username: 'admin1',
210
+ age: 25,
211
+ userType: 'admin',
212
+ email: 'admin@example.com'
213
+ };
214
+
215
+ const userData2 = {
216
+ username: 'user1',
217
+ age: 16,
218
+ userType: 'user',
219
+ email: ''
220
+ };
221
+
222
+ validateUser(userData1);
223
+ validateUser(userData2);
224
+
225
+ // ============================================
226
+ // 示例8:异步验证 - .validateAsync()
227
+ // ============================================
228
+ console.log('\n【示例8】异步验证 - .validateAsync()');
229
+ console.log('----------------------------');
230
+
231
+ async function asyncRegister() {
232
+ const ageValidator = dsl.if(d => d.age < 18)
233
+ .message('未成年用户不能注册');
234
+
235
+ // 验证通过
236
+ try {
237
+ const data1 = await ageValidator.validateAsync({ age: 20, name: '张三' });
238
+ console.log('✅ 验证通过:', data1.name);
239
+ } catch (error) {
240
+ console.log('❌ 验证失败:', error.message);
241
+ }
242
+
243
+ // 验证失败
244
+ try {
245
+ await ageValidator.validateAsync({ age: 16, name: '李四' });
246
+ } catch (error) {
247
+ console.log('❌ 验证失败:', error.message);
248
+ }
249
+ }
250
+
251
+ asyncRegister();
252
+
253
+ // ============================================
254
+ // 示例9:断言验证 - .assert()
255
+ // ============================================
256
+ console.log('\n【示例9】断言验证 - .assert()');
257
+ console.log('----------------------------');
258
+
259
+ function createUser(userData) {
260
+ try {
261
+ // 断言验证,失败直接抛错
262
+ dsl.if(d => d.age < 18)
263
+ .message('未成年用户不能注册')
264
+ .assert(userData);
265
+
266
+ dsl.if(d => !d.email || d.email.length === 0)
267
+ .message('邮箱不能为空')
268
+ .assert(userData);
269
+
270
+ console.log(`✅ 用户 ${userData.name} 创建成功`);
271
+ return { success: true, user: userData };
272
+ } catch (error) {
273
+ console.log(`❌ 用户 ${userData.name} 创建失败: ${error.message}`);
274
+ return { success: false, error: error.message };
275
+ }
276
+ }
277
+
278
+ createUser({ name: '张三', age: 20, email: 'zhangsan@example.com' });
279
+ createUser({ name: '李四', age: 16, email: 'lisi@example.com' });
280
+ createUser({ name: '王五', age: 20, email: '' });
281
+
282
+ // ============================================
283
+ // 示例10:Express 中间件场景(模拟)
284
+ // ============================================
285
+ console.log('\n【示例10】Express 中间件场景(模拟)');
286
+ console.log('----------------------------');
287
+
288
+ // 模拟 Express 中间件
289
+ async function checkPermission(req, res, next) {
290
+ try {
291
+ await dsl.if(d => d.role !== 'admin' && d.role !== 'moderator')
292
+ .message('权限不足')
293
+ .validateAsync(req.user);
294
+
295
+ console.log('✅ 权限验证通过');
296
+ next();
297
+ } catch (error) {
298
+ console.log('❌ 权限不足:', error.message);
299
+ res.status = 403;
300
+ res.error = error.message;
301
+ }
302
+ }
303
+
304
+ // 模拟请求
305
+ const mockReq1 = { user: { name: 'admin', role: 'admin' } };
306
+ const mockReq2 = { user: { name: 'user', role: 'user' } };
307
+ const mockRes = { status: 200, error: null };
308
+ const mockNext = () => console.log(' 继续处理请求...');
309
+
310
+ (async () => {
311
+ console.log('请求1 - 管理员:');
312
+ await checkPermission(mockReq1, mockRes, mockNext);
313
+
314
+ console.log('请求2 - 普通用户:');
315
+ await checkPermission(mockReq2, mockRes, mockNext);
316
+ })();
317
+
318
+ console.log('\n========================================');
319
+ console.log('示例运行完成!');
320
+ console.log('========================================');
321
+
@@ -0,0 +1,181 @@
1
+ /**
2
+ * I18nError 使用示例
3
+ *
4
+ * 统一的多语言错误抛出机制
5
+ *
6
+ * @version 1.1.1
7
+ */
8
+
9
+ const { I18nError, dsl, Locale } = require('../index');
10
+
11
+ console.log('=== I18nError 使用示例 ===\n');
12
+
13
+ // ========== 1. 基础用法 ==========
14
+ console.log('1. 基础用法:');
15
+ try {
16
+ throw I18nError.create('account.notFound');
17
+ } catch (error) {
18
+ console.log('错误:', error.message); // "账户不存在"
19
+ console.log('代码:', error.code); // "account.notFound"
20
+ }
21
+
22
+ // ========== 2. 带参数的错误 ==========
23
+ console.log('\n2. 带参数的错误:');
24
+ try {
25
+ throw I18nError.create('account.insufficientBalance', {
26
+ balance: 50,
27
+ required: 100
28
+ });
29
+ } catch (error) {
30
+ console.log('错误:', error.message); // "余额不足,当前余额50,需要100"
31
+ }
32
+
33
+ // ========== 3. 使用 throw 方法 ==========
34
+ console.log('\n3. 使用 throw 方法(直接抛错):');
35
+ try {
36
+ I18nError.throw('user.noPermission');
37
+ } catch (error) {
38
+ console.log('错误:', error.message); // "没有管理员权限"
39
+ }
40
+
41
+ // ========== 4. 使用 assert 断言 ==========
42
+ console.log('\n4. 使用 assert 断言:');
43
+ const account = { balance: 50 };
44
+
45
+ try {
46
+ I18nError.assert(account.balance >= 100, 'account.insufficientBalance', {
47
+ balance: account.balance,
48
+ required: 100
49
+ });
50
+ } catch (error) {
51
+ console.log('错误:', error.message);
52
+ }
53
+
54
+ // ========== 5. dsl.error 快捷方法 ==========
55
+ console.log('\n5. dsl.error 快捷方法:');
56
+ try {
57
+ dsl.error.throw('order.notPaid');
58
+ } catch (error) {
59
+ console.log('错误:', error.message); // "订单未支付"
60
+ }
61
+
62
+ // ========== 6. 多语言支持 ==========
63
+ console.log('\n6. 多语言支持:');
64
+ try {
65
+ // 中文
66
+ Locale.setLocale('zh-CN');
67
+ throw I18nError.create('account.notFound');
68
+ } catch (error) {
69
+ console.log('中文:', error.message); // "账户不存在"
70
+ }
71
+
72
+ try {
73
+ // 英文
74
+ Locale.setLocale('en-US');
75
+ throw I18nError.create('account.notFound');
76
+ } catch (error) {
77
+ console.log('英文:', error.message); // "Account not found"
78
+ }
79
+
80
+ // 恢复中文
81
+ Locale.setLocale('zh-CN');
82
+
83
+ // ========== 7. 实际业务场景 =========
84
+ console.log('\n7. 实际业务场景:');
85
+
86
+ // 场景1:账户验证函数
87
+ function getAccount(id) {
88
+ const account = id === '123' ? { id: '123', balance: 50, status: 'active' } : null;
89
+
90
+ // 断言账户存在
91
+ I18nError.assert(account, 'account.notFound');
92
+
93
+ // 断言账户状态
94
+ I18nError.assert(account.status === 'active', 'account.inactive');
95
+
96
+ // 断言余额充足
97
+ I18nError.assert(
98
+ account.balance >= 100,
99
+ 'account.insufficientBalance',
100
+ { balance: account.balance, required: 100 }
101
+ );
102
+
103
+ return account;
104
+ }
105
+
106
+ try {
107
+ getAccount('123');
108
+ } catch (error) {
109
+ console.log('业务错误:', error.message);
110
+ console.log('错误代码:', error.code);
111
+ }
112
+
113
+ // 场景2:与 dsl.if 结合
114
+ console.log('\n8. 与 dsl.if 结合使用:');
115
+ function validateUser(user) {
116
+ // 使用 dsl.if 进行数据验证
117
+ dsl.if(d => !d)
118
+ .message('user.notFound')
119
+ .and(d => !d.isVerified)
120
+ .message('user.notVerified')
121
+ .assert(user);
122
+
123
+ // 使用 I18nError 进行业务逻辑验证
124
+ I18nError.assert(user.role === 'admin', 'user.noPermission');
125
+ }
126
+
127
+ try {
128
+ validateUser({ isVerified: true, role: 'user' });
129
+ } catch (error) {
130
+ console.log('验证错误:', error.message);
131
+ }
132
+
133
+ // ========== 9. Express/Koa 中间件 ==========
134
+ console.log('\n9. Express/Koa 错误处理:');
135
+
136
+ // Express 错误处理中间件
137
+ function expressErrorHandler(error, req, res, next) {
138
+ if (error instanceof I18nError) {
139
+ return res.status(error.statusCode).json(error.toJSON());
140
+ }
141
+ next(error);
142
+ }
143
+
144
+ // 模拟使用
145
+ const mockError = I18nError.create('account.notFound', {}, 404);
146
+ const mockRes = {
147
+ status: (code) => {
148
+ console.log('HTTP Status:', code);
149
+ return mockRes;
150
+ },
151
+ json: (data) => {
152
+ console.log('Response:', JSON.stringify(data, null, 2));
153
+ return mockRes;
154
+ }
155
+ };
156
+
157
+ expressErrorHandler(mockError, {}, mockRes, () => {});
158
+
159
+ // ========== 10. 自定义状态码 ==========
160
+ console.log('\n10. 自定义状态码:');
161
+ try {
162
+ throw I18nError.create('user.notFound', {}, 404);
163
+ } catch (error) {
164
+ console.log('状态码:', error.statusCode); // 404
165
+ console.log('错误:', error.message);
166
+ }
167
+
168
+ // ========== 11. 错误检查 ==========
169
+ console.log('\n11. 错误类型检查:');
170
+ try {
171
+ throw I18nError.create('account.notFound');
172
+ } catch (error) {
173
+ if (error instanceof I18nError) {
174
+ console.log('是 I18nError:', true);
175
+ console.log('是账户不存在:', error.is('account.notFound'));
176
+ console.log('是用户不存在:', error.is('user.notFound'));
177
+ }
178
+ }
179
+
180
+ console.log('\n=== 示例完成 ===');
181
+