schema-dsl 1.2.5 → 2.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 (243) hide show
  1. package/CHANGELOG.md +130 -238
  2. package/LICENSE +21 -21
  3. package/README.md +628 -2486
  4. package/dist/DslBuilder-BIgQOAXp.d.ts +343 -0
  5. package/dist/DslBuilder-CjHTucNQ.d.cts +343 -0
  6. package/dist/Validator-CllRdrY0.d.ts +192 -0
  7. package/dist/Validator-D6okG9tr.d.cts +192 -0
  8. package/dist/index.cjs +6640 -0
  9. package/dist/index.d.cts +1151 -0
  10. package/dist/index.d.ts +1151 -0
  11. package/dist/index.js +6574 -0
  12. package/dist/plugin-CIKtTMtS.d.cts +246 -0
  13. package/dist/plugin-CIKtTMtS.d.ts +246 -0
  14. package/dist/plugins/custom-format.cjs +3818 -0
  15. package/dist/plugins/custom-format.d.cts +12 -0
  16. package/dist/plugins/custom-format.d.ts +12 -0
  17. package/dist/plugins/custom-format.js +3788 -0
  18. package/dist/plugins/custom-type-example.cjs +3811 -0
  19. package/dist/plugins/custom-type-example.d.cts +8 -0
  20. package/dist/plugins/custom-type-example.d.ts +8 -0
  21. package/dist/plugins/custom-type-example.js +3781 -0
  22. package/dist/plugins/custom-validator.cjs +144 -0
  23. package/dist/plugins/custom-validator.d.cts +10 -0
  24. package/dist/plugins/custom-validator.d.ts +10 -0
  25. package/dist/plugins/custom-validator.js +119 -0
  26. package/docs/FEATURE-INDEX.md +553 -519
  27. package/docs/add-custom-locale.md +496 -483
  28. package/docs/add-keyword.md +24 -0
  29. package/docs/api-reference.md +1047 -805
  30. package/docs/api.md +13 -0
  31. package/docs/best-practices-project-structure.md +417 -408
  32. package/docs/best-practices.md +712 -672
  33. package/docs/cache-manager.md +344 -336
  34. package/docs/compile.md +45 -0
  35. package/docs/conditional-api.md +1307 -1278
  36. package/docs/custom-extensions-guide.md +339 -411
  37. package/docs/design-philosophy.md +606 -601
  38. package/docs/doc-index.md +324 -0
  39. package/docs/dsl-syntax.md +714 -664
  40. package/docs/dynamic-locale.md +608 -598
  41. package/docs/enum.md +482 -475
  42. package/docs/error-handling.md +1975 -1966
  43. package/docs/export-guide.md +501 -462
  44. package/docs/export-limitations.md +567 -551
  45. package/docs/faq.md +596 -577
  46. package/docs/frontend-i18n-guide.md +307 -293
  47. package/docs/i18n-user-guide.md +487 -474
  48. package/docs/i18n.md +476 -457
  49. package/docs/index.md +48 -0
  50. package/docs/json-schema-basics.md +40 -0
  51. package/docs/label-vs-description.md +271 -262
  52. package/docs/markdown-exporter.md +406 -397
  53. package/docs/mongodb-exporter.md +302 -295
  54. package/docs/multi-language.md +26 -0
  55. package/docs/multi-type-support.md +322 -329
  56. package/docs/mysql-exporter.md +280 -273
  57. package/docs/number-operators.md +449 -442
  58. package/docs/optional-marker-guide.md +326 -321
  59. package/docs/performance-guide.md +49 -0
  60. package/docs/plugin-system.md +381 -542
  61. package/docs/plugin-type-registration.md +34 -0
  62. package/docs/postgresql-exporter.md +311 -304
  63. package/docs/public/favicon.svg +5 -0
  64. package/docs/quick-start.md +435 -761
  65. package/docs/runtime-locale-support.md +532 -521
  66. package/docs/schema-helper.md +345 -340
  67. package/docs/schema-utils-advanced-issues.md +23 -0
  68. package/docs/schema-utils-best-practices.md +20 -0
  69. package/docs/schema-utils-chaining.md +150 -143
  70. package/docs/schema-utils.md +524 -490
  71. package/docs/security-checklist.md +20 -0
  72. package/docs/string-extensions.md +488 -480
  73. package/docs/troubleshooting.md +486 -471
  74. package/docs/type-converter.md +310 -319
  75. package/docs/type-reference.md +242 -219
  76. package/docs/typescript-guide.md +584 -573
  77. package/docs/union-type-guide.md +157 -147
  78. package/docs/union-types.md +284 -277
  79. package/docs/validate-async.md +491 -480
  80. package/docs/validate-batch.md +49 -0
  81. package/docs/validate-dsl-object-support.md +578 -573
  82. package/docs/validate.md +506 -486
  83. package/docs/validation-guide.md +502 -484
  84. package/docs/validator.md +39 -0
  85. package/package.json +131 -73
  86. package/plugins/custom-format.cjs +8 -0
  87. package/plugins/custom-type-example.cjs +8 -0
  88. package/plugins/custom-validator.cjs +8 -0
  89. package/src/adapters/DslAdapter.ts +111 -0
  90. package/src/adapters/index.ts +1 -0
  91. package/src/config/constants.ts +83 -0
  92. package/src/config/index.ts +2 -0
  93. package/src/config/patterns.ts +77 -0
  94. package/src/core/CacheManager.ts +169 -0
  95. package/src/core/ConditionalBuilder.ts +382 -0
  96. package/src/core/ConditionalRuntime.ts +28 -0
  97. package/src/core/ConditionalValidator.ts +255 -0
  98. package/src/core/DslBuilder.ts +687 -0
  99. package/src/core/ErrorCodes.ts +38 -0
  100. package/src/core/ErrorFormatter.ts +271 -0
  101. package/src/core/JSONSchemaCore.ts +65 -0
  102. package/src/core/Locale.ts +187 -0
  103. package/src/core/MessageTemplate.ts +42 -0
  104. package/src/core/ObjectDslBuilder.ts +64 -0
  105. package/src/core/PluginManager.ts +326 -0
  106. package/src/core/StringExtensions.ts +140 -0
  107. package/src/core/TemplateEngine.ts +44 -0
  108. package/src/core/Validator.ts +448 -0
  109. package/src/errors/I18nError.ts +159 -0
  110. package/src/errors/ValidationError.ts +105 -0
  111. package/src/exporters/BaseExporter.ts +60 -0
  112. package/src/exporters/MarkdownExporter.ts +305 -0
  113. package/src/exporters/MongoDBExporter.ts +126 -0
  114. package/src/exporters/MySQLExporter.ts +156 -0
  115. package/src/exporters/PostgreSQLExporter.ts +222 -0
  116. package/src/exporters/index.ts +18 -0
  117. package/src/index.ts +651 -0
  118. package/{lib/locales/en-US.js → src/locales/en-US.ts} +160 -176
  119. package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +160 -113
  120. package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +160 -113
  121. package/src/locales/index.ts +103 -0
  122. package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +160 -118
  123. package/src/locales/types.ts +156 -0
  124. package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +160 -177
  125. package/src/parser/ConstraintParser.ts +101 -0
  126. package/src/parser/DslParser.ts +470 -0
  127. package/src/parser/SchemaCompiler.ts +66 -0
  128. package/src/parser/TypeRegistry.ts +250 -0
  129. package/src/parser/index.ts +6 -0
  130. package/src/plugins/custom-format.ts +124 -0
  131. package/src/plugins/custom-type-example.ts +106 -0
  132. package/src/plugins/custom-validator.ts +138 -0
  133. package/src/types/conditional.ts +28 -0
  134. package/src/types/config.ts +59 -0
  135. package/src/types/dsl.ts +131 -0
  136. package/src/types/error.ts +60 -0
  137. package/src/types/index.ts +17 -0
  138. package/src/types/infer.ts +128 -0
  139. package/src/types/plugin.ts +58 -0
  140. package/src/types/safe-regex.d.ts +9 -0
  141. package/src/types/schema.ts +66 -0
  142. package/src/types/validate.ts +71 -0
  143. package/src/utils/SchemaHelper.ts +196 -0
  144. package/src/utils/SchemaUtils.ts +365 -0
  145. package/src/utils/TypeConverter.ts +215 -0
  146. package/src/utils/index.ts +10 -0
  147. package/src/validators/CustomKeywords.ts +477 -0
  148. package/.eslintignore +0 -11
  149. package/.eslintrc.json +0 -27
  150. package/CONTRIBUTING.md +0 -368
  151. package/STATUS.md +0 -491
  152. package/changelogs/v1.0.0.md +0 -328
  153. package/changelogs/v1.0.9.md +0 -367
  154. package/changelogs/v1.1.0.md +0 -389
  155. package/changelogs/v1.1.1.md +0 -308
  156. package/changelogs/v1.1.2.md +0 -183
  157. package/changelogs/v1.1.3.md +0 -161
  158. package/changelogs/v1.1.4.md +0 -432
  159. package/changelogs/v1.1.5.md +0 -493
  160. package/changelogs/v1.1.6.md +0 -211
  161. package/changelogs/v1.1.8.md +0 -376
  162. package/changelogs/v1.2.3.md +0 -124
  163. package/docs/INDEX.md +0 -252
  164. package/docs/issues-resolved-summary.md +0 -196
  165. package/docs/performance-benchmark-report.md +0 -179
  166. package/docs/performance-quick-reference.md +0 -123
  167. package/docs/user-questions-answered.md +0 -353
  168. package/docs/validation-rules-v1.0.2.md +0 -1608
  169. package/examples/README.md +0 -81
  170. package/examples/array-dsl-example.js +0 -227
  171. package/examples/conditional-example.js +0 -288
  172. package/examples/conditional-non-object.js +0 -129
  173. package/examples/conditional-validate-example.js +0 -321
  174. package/examples/custom-extension.js +0 -85
  175. package/examples/dsl-match-example.js +0 -74
  176. package/examples/dsl-style.js +0 -118
  177. package/examples/dynamic-locale-configuration.js +0 -348
  178. package/examples/dynamic-locale-example.js +0 -287
  179. package/examples/enum.examples.js +0 -324
  180. package/examples/export-demo.js +0 -130
  181. package/examples/express-integration.js +0 -376
  182. package/examples/i18n-error-handling-complete.js +0 -381
  183. package/examples/i18n-error-handling-quickstart.md +0 -0
  184. package/examples/i18n-error.examples.js +0 -181
  185. package/examples/i18n-full-demo.js +0 -301
  186. package/examples/i18n-memory-safety.examples.js +0 -268
  187. package/examples/markdown-export.js +0 -71
  188. package/examples/middleware-usage.js +0 -93
  189. package/examples/new-features-comparison.js +0 -315
  190. package/examples/password-reset/README.md +0 -153
  191. package/examples/password-reset/schema.js +0 -26
  192. package/examples/password-reset/test.js +0 -101
  193. package/examples/plugin-system.examples.js +0 -205
  194. package/examples/schema-utils-chaining.examples.js +0 -250
  195. package/examples/simple-example.js +0 -122
  196. package/examples/slug.examples.js +0 -179
  197. package/examples/string-extensions.js +0 -297
  198. package/examples/union-type-example.js +0 -127
  199. package/examples/union-types-example.js +0 -77
  200. package/examples/user-registration/README.md +0 -156
  201. package/examples/user-registration/routes.js +0 -92
  202. package/examples/user-registration/schema.js +0 -150
  203. package/examples/user-registration/server.js +0 -74
  204. package/index.d.ts +0 -3658
  205. package/index.js +0 -475
  206. package/index.mjs +0 -60
  207. package/lib/adapters/DslAdapter.js +0 -995
  208. package/lib/adapters/index.js +0 -20
  209. package/lib/config/constants.js +0 -286
  210. package/lib/config/patterns/common.js +0 -47
  211. package/lib/config/patterns/creditCard.js +0 -9
  212. package/lib/config/patterns/idCard.js +0 -9
  213. package/lib/config/patterns/index.js +0 -9
  214. package/lib/config/patterns/licensePlate.js +0 -4
  215. package/lib/config/patterns/passport.js +0 -4
  216. package/lib/config/patterns/phone.js +0 -9
  217. package/lib/config/patterns/postalCode.js +0 -5
  218. package/lib/core/CacheManager.js +0 -376
  219. package/lib/core/ConditionalBuilder.js +0 -503
  220. package/lib/core/DslBuilder.js +0 -1589
  221. package/lib/core/ErrorCodes.js +0 -233
  222. package/lib/core/ErrorFormatter.js +0 -445
  223. package/lib/core/JSONSchemaCore.js +0 -347
  224. package/lib/core/Locale.js +0 -130
  225. package/lib/core/MessageTemplate.js +0 -98
  226. package/lib/core/PluginManager.js +0 -448
  227. package/lib/core/StringExtensions.js +0 -240
  228. package/lib/core/Validator.js +0 -654
  229. package/lib/errors/I18nError.js +0 -328
  230. package/lib/errors/ValidationError.js +0 -191
  231. package/lib/exporters/MarkdownExporter.js +0 -420
  232. package/lib/exporters/MongoDBExporter.js +0 -162
  233. package/lib/exporters/MySQLExporter.js +0 -212
  234. package/lib/exporters/PostgreSQLExporter.js +0 -289
  235. package/lib/exporters/index.js +0 -24
  236. package/lib/locales/index.js +0 -8
  237. package/lib/utils/LRUCache.js +0 -174
  238. package/lib/utils/SchemaHelper.js +0 -240
  239. package/lib/utils/SchemaUtils.js +0 -445
  240. package/lib/utils/TypeConverter.js +0 -245
  241. package/lib/utils/index.js +0 -13
  242. package/lib/validators/CustomKeywords.js +0 -616
  243. package/lib/validators/index.js +0 -11
@@ -1,381 +0,0 @@
1
- /**
2
- * schema-dsl 多语言错误处理完整示例
3
- *
4
- * 展示如何动态配置多语言来使用 dsl.error.throw('account.notFound')
5
- *
6
- * @version 1.1.5+
7
- * @author schema-dsl Team
8
- */
9
-
10
- const { dsl, Locale } = require('schema-dsl');
11
-
12
- // ============================================================
13
- // 第一步:配置语言包
14
- // ============================================================
15
-
16
- console.log('📚 步骤1:配置多语言包\n');
17
-
18
- // 方式1:使用 Locale.addLocale() 添加单个语言
19
- Locale.addLocale('zh-CN', {
20
- // 字符串格式(向后兼容)
21
- 'user.notFound': '用户不存在',
22
-
23
- // 对象格式(v1.1.5+ 推荐)- 统一数字错误码
24
- 'account.notFound': {
25
- code: 40001,
26
- message: '账户不存在'
27
- },
28
- 'account.insufficientBalance': {
29
- code: 40002,
30
- message: '余额不足,当前余额{{#balance}}元,需要{{#required}}元'
31
- },
32
- 'order.notPaid': {
33
- code: 50001,
34
- message: '订单未支付'
35
- },
36
- 'permission.denied': {
37
- code: 40003,
38
- message: '您没有权限执行此操作'
39
- }
40
- });
41
-
42
- Locale.addLocale('en-US', {
43
- 'user.notFound': 'User not found',
44
-
45
- 'account.notFound': {
46
- code: 40001, // 相同的数字码
47
- message: 'Account not found'
48
- },
49
- 'account.insufficientBalance': {
50
- code: 40002,
51
- message: 'Insufficient balance: current {{#balance}}, required {{#required}}'
52
- },
53
- 'order.notPaid': {
54
- code: 50001,
55
- message: 'Order not paid'
56
- },
57
- 'permission.denied': {
58
- code: 40003,
59
- message: 'Permission denied'
60
- }
61
- });
62
-
63
- Locale.addLocale('ja-JP', {
64
- 'user.notFound': 'ユーザーが見つかりません',
65
-
66
- 'account.notFound': {
67
- code: 40001,
68
- message: 'アカウントが見つかりません'
69
- },
70
- 'account.insufficientBalance': {
71
- code: 40002,
72
- message: '残高不足: 現在{{#balance}}、必要{{#required}}'
73
- },
74
- 'order.notPaid': {
75
- code: 50001,
76
- message: '注文が未払いです'
77
- },
78
- 'permission.denied': {
79
- code: 40003,
80
- message: 'アクセス権限がありません'
81
- }
82
- });
83
-
84
- // 方式2:批量配置(使用 dsl.config)
85
- dsl.config({
86
- i18n: {
87
- 'zh-CN': {
88
- 'payment.failed': {
89
- code: 50002,
90
- message: '支付失败:{{#reason}}'
91
- }
92
- },
93
- 'en-US': {
94
- 'payment.failed': {
95
- code: 50002,
96
- message: 'Payment failed: {{#reason}}'
97
- }
98
- }
99
- }
100
- });
101
-
102
- console.log('✅ 语言包配置完成\n');
103
-
104
- // ============================================================
105
- // 第二步:设置默认语言
106
- // ============================================================
107
-
108
- console.log('📚 步骤2:设置默认语言\n');
109
-
110
- Locale.setLocale('zh-CN');
111
- console.log(`✅ 默认语言设置为: ${Locale.getLocale()}\n`);
112
-
113
- // ============================================================
114
- // 第三步:使用 dsl.error 抛出多语言错误
115
- // ============================================================
116
-
117
- console.log('📚 步骤3:使用 dsl.error 抛出多语言错误\n');
118
-
119
- // 3.1 使用默认语言(全局语言)
120
- console.log('--- 3.1 使用默认语言(全局语言)---');
121
- try {
122
- dsl.error.throw('account.notFound');
123
- } catch (error) {
124
- console.log('错误码:', error.code); // 40001
125
- console.log('原始Key:', error.originalKey); // 'account.notFound'
126
- console.log('错误消息:', error.message); // '账户不存在'
127
- console.log('语言:', error.locale); // 'zh-CN'
128
- console.log('状态码:', error.statusCode); // 400
129
- console.log();
130
- }
131
-
132
- // 3.2 运行时指定语言(推荐用于API)⭐
133
- console.log('--- 3.2 运行时指定语言(英文)---');
134
- try {
135
- dsl.error.throw('account.notFound', {}, 404, 'en-US');
136
- } catch (error) {
137
- console.log('错误码:', error.code); // 40001
138
- console.log('原始Key:', error.originalKey); // 'account.notFound'
139
- console.log('错误消息:', error.message); // 'Account not found'
140
- console.log('语言:', error.locale); // 'en-US'
141
- console.log();
142
- }
143
-
144
- // 3.3 带参数的错误消息
145
- console.log('--- 3.3 带参数的错误消息(中文)---');
146
- try {
147
- dsl.error.throw('account.insufficientBalance', {
148
- balance: 50,
149
- required: 100
150
- }, 400, 'zh-CN');
151
- } catch (error) {
152
- console.log('错误消息:', error.message);
153
- // '余额不足,当前余额50元,需要100元'
154
- console.log('参数:', error.params);
155
- console.log();
156
- }
157
-
158
- console.log('--- 3.4 带参数的错误消息(英文)---');
159
- try {
160
- dsl.error.throw('account.insufficientBalance', {
161
- balance: 50,
162
- required: 100
163
- }, 400, 'en-US');
164
- } catch (error) {
165
- console.log('错误消息:', error.message);
166
- // 'Insufficient balance: current 50, required 100'
167
- console.log();
168
- }
169
-
170
- // ============================================================
171
- // 第四步:使用 dsl.error.create(创建但不抛出)
172
- // ============================================================
173
-
174
- console.log('📚 步骤4:使用 dsl.error.create(创建但不抛出)\n');
175
-
176
- const error1 = dsl.error.create('account.notFound', {}, 404, 'zh-CN');
177
- console.log('中文错误:', error1.message);
178
-
179
- const error2 = dsl.error.create('account.notFound', {}, 404, 'en-US');
180
- console.log('英文错误:', error2.message);
181
-
182
- const error3 = dsl.error.create('account.notFound', {}, 404, 'ja-JP');
183
- console.log('日文错误:', error3.message);
184
- console.log();
185
-
186
- // ============================================================
187
- // 第五步:使用 dsl.error.assert(断言方式)
188
- // ============================================================
189
-
190
- console.log('📚 步骤5:使用 dsl.error.assert(断言方式)\n');
191
-
192
- // 模拟数据
193
- const account = null;
194
- const user = { role: 'user' };
195
-
196
- // 5.1 断言账户存在
197
- console.log('--- 5.1 断言账户存在(中文)---');
198
- try {
199
- dsl.error.assert(account, 'account.notFound', {}, 404, 'zh-CN');
200
- console.log('账户存在');
201
- } catch (error) {
202
- console.log('断言失败:', error.message);
203
- console.log();
204
- }
205
-
206
- // 5.2 断言权限
207
- console.log('--- 5.2 断言权限(英文)---');
208
- try {
209
- dsl.error.assert(
210
- user.role === 'admin',
211
- 'permission.denied',
212
- {},
213
- 403,
214
- 'en-US'
215
- );
216
- console.log('权限通过');
217
- } catch (error) {
218
- console.log('断言失败:', error.message);
219
- console.log();
220
- }
221
-
222
- // ============================================================
223
- // 第六步:错误判断(error.is())
224
- // ============================================================
225
-
226
- console.log('📚 步骤6:错误判断(error.is())\n');
227
-
228
- try {
229
- dsl.error.throw('account.notFound');
230
- } catch (error) {
231
- // 方式1:使用 originalKey 判断
232
- if (error.is('account.notFound')) {
233
- console.log('✅ 使用 originalKey 判断成功');
234
- }
235
-
236
- // 方式2:使用数字 code 判断(v1.1.5+)
237
- if (error.is(40001)) {
238
- console.log('✅ 使用数字 code 判断成功');
239
- }
240
- console.log();
241
- }
242
-
243
- // ============================================================
244
- // 第七步:Express/Koa 中的实际应用
245
- // ============================================================
246
-
247
- console.log('📚 步骤7:Express/Koa 中的实际应用\n');
248
-
249
- // 模拟 Express 请求处理
250
- function expressHandler(req, res) {
251
- try {
252
- // 从请求头获取语言
253
- const locale = req.headers['accept-language'] || 'zh-CN';
254
-
255
- // 模拟业务逻辑
256
- const account = findAccount(req.params.id);
257
-
258
- // 使用运行时语言抛出错误
259
- dsl.error.assert(account, 'account.notFound', {}, 404, locale);
260
-
261
- // 检查余额
262
- dsl.error.assert(
263
- account.balance >= req.body.amount,
264
- 'account.insufficientBalance',
265
- {
266
- balance: account.balance,
267
- required: req.body.amount
268
- },
269
- 400,
270
- locale
271
- );
272
-
273
- res.json({ success: true, account });
274
- } catch (error) {
275
- // 返回多语言错误
276
- res.status(error.statusCode).json(error.toJSON());
277
- }
278
- }
279
-
280
- // 模拟中文请求
281
- console.log('--- 模拟中文请求 ---');
282
- const req1 = {
283
- headers: { 'accept-language': 'zh-CN' },
284
- params: { id: '123' },
285
- body: { amount: 100 }
286
- };
287
- const res1 = {
288
- json: (data) => console.log('响应:', JSON.stringify(data, null, 2)),
289
- status: (code) => ({ json: (data) => {
290
- console.log(`状态码: ${code}`);
291
- console.log('响应:', JSON.stringify(data, null, 2));
292
- }})
293
- };
294
- expressHandler(req1, res1);
295
- console.log();
296
-
297
- // 模拟英文请求
298
- console.log('--- 模拟英文请求 ---');
299
- const req2 = {
300
- headers: { 'accept-language': 'en-US' },
301
- params: { id: '123' },
302
- body: { amount: 100 }
303
- };
304
- const res2 = {
305
- json: (data) => console.log('响应:', JSON.stringify(data, null, 2)),
306
- status: (code) => ({ json: (data) => {
307
- console.log(`状态码: ${code}`);
308
- console.log('响应:', JSON.stringify(data, null, 2));
309
- }})
310
- };
311
- expressHandler(req2, res2);
312
- console.log();
313
-
314
- // ============================================================
315
- // 第八步:前端统一错误处理
316
- // ============================================================
317
-
318
- console.log('📚 步骤8:前端统一错误处理示例\n');
319
-
320
- // 前端错误处理示例(JavaScript)
321
- const frontendErrorHandler = `
322
- // 前端统一错误处理(使用数字 code)
323
- async function handleRequest() {
324
- try {
325
- const response = await fetch('/api/account/123');
326
- const data = await response.json();
327
-
328
- if (!response.ok) {
329
- throw data; // 服务端返回的错误对象
330
- }
331
-
332
- return data;
333
- } catch (error) {
334
- // 根据数字 code 统一处理,不受语言影响
335
- switch (error.code) {
336
- case 40001: // ACCOUNT_NOT_FOUND
337
- showNotFoundPage();
338
- break;
339
- case 40002: // INSUFFICIENT_BALANCE
340
- showTopUpDialog(error.params);
341
- break;
342
- case 50001: // ORDER_NOT_PAID
343
- showPaymentDialog();
344
- break;
345
- default:
346
- showGenericError(error.message);
347
- }
348
- }
349
- }
350
- `;
351
-
352
- console.log(frontendErrorHandler);
353
-
354
- // ============================================================
355
- // 工具函数
356
- // ============================================================
357
-
358
- function findAccount(id) {
359
- // 模拟查询失败
360
- return null;
361
- }
362
-
363
- // ============================================================
364
- // 总结
365
- // ============================================================
366
-
367
- console.log('\n📝 总结\n');
368
- console.log('✅ 1. 使用 Locale.addLocale() 或 dsl.config() 配置语言包');
369
- console.log('✅ 2. 使用 Locale.setLocale() 设置默认语言');
370
- console.log('✅ 3. 使用 dsl.error.throw() 抛出多语言错误');
371
- console.log('✅ 4. 使用 dsl.error.create() 创建错误(不抛出)');
372
- console.log('✅ 5. 使用 dsl.error.assert() 断言式错误处理');
373
- console.log('✅ 6. 使用 error.is() 判断错误类型(支持 key 和 code)');
374
- console.log('✅ 7. API 开发中使用运行时语言(推荐)');
375
- console.log('✅ 8. 前端使用统一的数字 code 处理错误');
376
- console.log('\n🎯 关键点:');
377
- console.log(' - 对象格式支持统一数字错误码(v1.1.5+)');
378
- console.log(' - 运行时语言不改变全局状态(并发安全)');
379
- console.log(' - 完全向后兼容字符串格式');
380
- console.log(' - 多语言共享相同的数字 code');
381
- console.log('\n📖 完整文档:docs/error-handling.md 和 docs/runtime-locale-support.md');
File without changes
@@ -1,181 +0,0 @@
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
-