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.
- package/CHANGELOG.md +130 -238
- package/LICENSE +21 -21
- package/README.md +628 -2486
- package/dist/DslBuilder-BIgQOAXp.d.ts +343 -0
- package/dist/DslBuilder-CjHTucNQ.d.cts +343 -0
- package/dist/Validator-CllRdrY0.d.ts +192 -0
- package/dist/Validator-D6okG9tr.d.cts +192 -0
- package/dist/index.cjs +6640 -0
- package/dist/index.d.cts +1151 -0
- package/dist/index.d.ts +1151 -0
- package/dist/index.js +6574 -0
- package/dist/plugin-CIKtTMtS.d.cts +246 -0
- package/dist/plugin-CIKtTMtS.d.ts +246 -0
- package/dist/plugins/custom-format.cjs +3818 -0
- package/dist/plugins/custom-format.d.cts +12 -0
- package/dist/plugins/custom-format.d.ts +12 -0
- package/dist/plugins/custom-format.js +3788 -0
- package/dist/plugins/custom-type-example.cjs +3811 -0
- package/dist/plugins/custom-type-example.d.cts +8 -0
- package/dist/plugins/custom-type-example.d.ts +8 -0
- package/dist/plugins/custom-type-example.js +3781 -0
- package/dist/plugins/custom-validator.cjs +144 -0
- package/dist/plugins/custom-validator.d.cts +10 -0
- package/dist/plugins/custom-validator.d.ts +10 -0
- package/dist/plugins/custom-validator.js +119 -0
- package/docs/FEATURE-INDEX.md +553 -519
- package/docs/add-custom-locale.md +496 -483
- package/docs/add-keyword.md +24 -0
- package/docs/api-reference.md +1047 -805
- package/docs/api.md +13 -0
- package/docs/best-practices-project-structure.md +417 -408
- package/docs/best-practices.md +712 -672
- package/docs/cache-manager.md +344 -336
- package/docs/compile.md +45 -0
- package/docs/conditional-api.md +1307 -1278
- package/docs/custom-extensions-guide.md +339 -411
- package/docs/design-philosophy.md +606 -601
- package/docs/doc-index.md +324 -0
- package/docs/dsl-syntax.md +714 -664
- package/docs/dynamic-locale.md +608 -598
- package/docs/enum.md +482 -475
- package/docs/error-handling.md +1975 -1966
- package/docs/export-guide.md +501 -462
- package/docs/export-limitations.md +567 -551
- package/docs/faq.md +596 -577
- package/docs/frontend-i18n-guide.md +307 -293
- package/docs/i18n-user-guide.md +487 -474
- package/docs/i18n.md +476 -457
- package/docs/index.md +48 -0
- package/docs/json-schema-basics.md +40 -0
- package/docs/label-vs-description.md +271 -262
- package/docs/markdown-exporter.md +406 -397
- package/docs/mongodb-exporter.md +302 -295
- package/docs/multi-language.md +26 -0
- package/docs/multi-type-support.md +322 -329
- package/docs/mysql-exporter.md +280 -273
- package/docs/number-operators.md +449 -442
- package/docs/optional-marker-guide.md +326 -321
- package/docs/performance-guide.md +49 -0
- package/docs/plugin-system.md +381 -542
- package/docs/plugin-type-registration.md +34 -0
- package/docs/postgresql-exporter.md +311 -304
- package/docs/public/favicon.svg +5 -0
- package/docs/quick-start.md +435 -761
- package/docs/runtime-locale-support.md +532 -521
- package/docs/schema-helper.md +345 -340
- package/docs/schema-utils-advanced-issues.md +23 -0
- package/docs/schema-utils-best-practices.md +20 -0
- package/docs/schema-utils-chaining.md +150 -143
- package/docs/schema-utils.md +524 -490
- package/docs/security-checklist.md +20 -0
- package/docs/string-extensions.md +488 -480
- package/docs/troubleshooting.md +486 -471
- package/docs/type-converter.md +310 -319
- package/docs/type-reference.md +242 -219
- package/docs/typescript-guide.md +584 -573
- package/docs/union-type-guide.md +157 -147
- package/docs/union-types.md +284 -277
- package/docs/validate-async.md +491 -480
- package/docs/validate-batch.md +49 -0
- package/docs/validate-dsl-object-support.md +578 -573
- package/docs/validate.md +506 -486
- package/docs/validation-guide.md +502 -484
- package/docs/validator.md +39 -0
- package/package.json +131 -73
- package/plugins/custom-format.cjs +8 -0
- package/plugins/custom-type-example.cjs +8 -0
- package/plugins/custom-validator.cjs +8 -0
- package/src/adapters/DslAdapter.ts +111 -0
- package/src/adapters/index.ts +1 -0
- package/src/config/constants.ts +83 -0
- package/src/config/index.ts +2 -0
- package/src/config/patterns.ts +77 -0
- package/src/core/CacheManager.ts +169 -0
- package/src/core/ConditionalBuilder.ts +382 -0
- package/src/core/ConditionalRuntime.ts +28 -0
- package/src/core/ConditionalValidator.ts +255 -0
- package/src/core/DslBuilder.ts +687 -0
- package/src/core/ErrorCodes.ts +38 -0
- package/src/core/ErrorFormatter.ts +271 -0
- package/src/core/JSONSchemaCore.ts +65 -0
- package/src/core/Locale.ts +187 -0
- package/src/core/MessageTemplate.ts +42 -0
- package/src/core/ObjectDslBuilder.ts +64 -0
- package/src/core/PluginManager.ts +326 -0
- package/src/core/StringExtensions.ts +140 -0
- package/src/core/TemplateEngine.ts +44 -0
- package/src/core/Validator.ts +448 -0
- package/src/errors/I18nError.ts +159 -0
- package/src/errors/ValidationError.ts +105 -0
- package/src/exporters/BaseExporter.ts +60 -0
- package/src/exporters/MarkdownExporter.ts +305 -0
- package/src/exporters/MongoDBExporter.ts +126 -0
- package/src/exporters/MySQLExporter.ts +156 -0
- package/src/exporters/PostgreSQLExporter.ts +222 -0
- package/src/exporters/index.ts +18 -0
- package/src/index.ts +651 -0
- package/{lib/locales/en-US.js → src/locales/en-US.ts} +160 -176
- package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +160 -113
- package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +160 -113
- package/src/locales/index.ts +103 -0
- package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +160 -118
- package/src/locales/types.ts +156 -0
- package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +160 -177
- package/src/parser/ConstraintParser.ts +101 -0
- package/src/parser/DslParser.ts +470 -0
- package/src/parser/SchemaCompiler.ts +66 -0
- package/src/parser/TypeRegistry.ts +250 -0
- package/src/parser/index.ts +6 -0
- package/src/plugins/custom-format.ts +124 -0
- package/src/plugins/custom-type-example.ts +106 -0
- package/src/plugins/custom-validator.ts +138 -0
- package/src/types/conditional.ts +28 -0
- package/src/types/config.ts +59 -0
- package/src/types/dsl.ts +131 -0
- package/src/types/error.ts +60 -0
- package/src/types/index.ts +17 -0
- package/src/types/infer.ts +128 -0
- package/src/types/plugin.ts +58 -0
- package/src/types/safe-regex.d.ts +9 -0
- package/src/types/schema.ts +66 -0
- package/src/types/validate.ts +71 -0
- package/src/utils/SchemaHelper.ts +196 -0
- package/src/utils/SchemaUtils.ts +365 -0
- package/src/utils/TypeConverter.ts +215 -0
- package/src/utils/index.ts +10 -0
- package/src/validators/CustomKeywords.ts +477 -0
- package/.eslintignore +0 -11
- package/.eslintrc.json +0 -27
- package/CONTRIBUTING.md +0 -368
- package/STATUS.md +0 -491
- package/changelogs/v1.0.0.md +0 -328
- package/changelogs/v1.0.9.md +0 -367
- package/changelogs/v1.1.0.md +0 -389
- package/changelogs/v1.1.1.md +0 -308
- package/changelogs/v1.1.2.md +0 -183
- package/changelogs/v1.1.3.md +0 -161
- package/changelogs/v1.1.4.md +0 -432
- package/changelogs/v1.1.5.md +0 -493
- package/changelogs/v1.1.6.md +0 -211
- package/changelogs/v1.1.8.md +0 -376
- package/changelogs/v1.2.3.md +0 -124
- package/docs/INDEX.md +0 -252
- package/docs/issues-resolved-summary.md +0 -196
- package/docs/performance-benchmark-report.md +0 -179
- package/docs/performance-quick-reference.md +0 -123
- package/docs/user-questions-answered.md +0 -353
- package/docs/validation-rules-v1.0.2.md +0 -1608
- package/examples/README.md +0 -81
- package/examples/array-dsl-example.js +0 -227
- package/examples/conditional-example.js +0 -288
- package/examples/conditional-non-object.js +0 -129
- package/examples/conditional-validate-example.js +0 -321
- package/examples/custom-extension.js +0 -85
- package/examples/dsl-match-example.js +0 -74
- package/examples/dsl-style.js +0 -118
- package/examples/dynamic-locale-configuration.js +0 -348
- package/examples/dynamic-locale-example.js +0 -287
- package/examples/enum.examples.js +0 -324
- package/examples/export-demo.js +0 -130
- package/examples/express-integration.js +0 -376
- package/examples/i18n-error-handling-complete.js +0 -381
- package/examples/i18n-error-handling-quickstart.md +0 -0
- package/examples/i18n-error.examples.js +0 -181
- package/examples/i18n-full-demo.js +0 -301
- package/examples/i18n-memory-safety.examples.js +0 -268
- package/examples/markdown-export.js +0 -71
- package/examples/middleware-usage.js +0 -93
- package/examples/new-features-comparison.js +0 -315
- package/examples/password-reset/README.md +0 -153
- package/examples/password-reset/schema.js +0 -26
- package/examples/password-reset/test.js +0 -101
- package/examples/plugin-system.examples.js +0 -205
- package/examples/schema-utils-chaining.examples.js +0 -250
- package/examples/simple-example.js +0 -122
- package/examples/slug.examples.js +0 -179
- package/examples/string-extensions.js +0 -297
- package/examples/union-type-example.js +0 -127
- package/examples/union-types-example.js +0 -77
- package/examples/user-registration/README.md +0 -156
- package/examples/user-registration/routes.js +0 -92
- package/examples/user-registration/schema.js +0 -150
- package/examples/user-registration/server.js +0 -74
- package/index.d.ts +0 -3658
- package/index.js +0 -475
- package/index.mjs +0 -60
- package/lib/adapters/DslAdapter.js +0 -995
- package/lib/adapters/index.js +0 -20
- package/lib/config/constants.js +0 -286
- package/lib/config/patterns/common.js +0 -47
- package/lib/config/patterns/creditCard.js +0 -9
- package/lib/config/patterns/idCard.js +0 -9
- package/lib/config/patterns/index.js +0 -9
- package/lib/config/patterns/licensePlate.js +0 -4
- package/lib/config/patterns/passport.js +0 -4
- package/lib/config/patterns/phone.js +0 -9
- package/lib/config/patterns/postalCode.js +0 -5
- package/lib/core/CacheManager.js +0 -376
- package/lib/core/ConditionalBuilder.js +0 -503
- package/lib/core/DslBuilder.js +0 -1589
- package/lib/core/ErrorCodes.js +0 -233
- package/lib/core/ErrorFormatter.js +0 -445
- package/lib/core/JSONSchemaCore.js +0 -347
- package/lib/core/Locale.js +0 -130
- package/lib/core/MessageTemplate.js +0 -98
- package/lib/core/PluginManager.js +0 -448
- package/lib/core/StringExtensions.js +0 -240
- package/lib/core/Validator.js +0 -654
- package/lib/errors/I18nError.js +0 -328
- package/lib/errors/ValidationError.js +0 -191
- package/lib/exporters/MarkdownExporter.js +0 -420
- package/lib/exporters/MongoDBExporter.js +0 -162
- package/lib/exporters/MySQLExporter.js +0 -212
- package/lib/exporters/PostgreSQLExporter.js +0 -289
- package/lib/exporters/index.js +0 -24
- package/lib/locales/index.js +0 -8
- package/lib/utils/LRUCache.js +0 -174
- package/lib/utils/SchemaHelper.js +0 -240
- package/lib/utils/SchemaUtils.js +0 -445
- package/lib/utils/TypeConverter.js +0 -245
- package/lib/utils/index.js +0 -13
- package/lib/validators/CustomKeywords.js +0 -616
- package/lib/validators/index.js +0 -11
|
@@ -1,483 +1,496 @@
|
|
|
1
|
-
# 添加自定义语言包指南
|
|
2
|
-
|
|
3
|
-
**版本**:
|
|
4
|
-
**最后更新**: 2026-
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 📖 概述
|
|
9
|
-
|
|
10
|
-
本指南将教你如何为 schema-dsl 添加自定义语言包或扩展现有语言。
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
│
|
|
29
|
-
│ ├──
|
|
30
|
-
│ │
|
|
31
|
-
│
|
|
32
|
-
│
|
|
33
|
-
│
|
|
34
|
-
│
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
'
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
'
|
|
134
|
-
'
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'
|
|
138
|
-
'
|
|
139
|
-
'
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
'
|
|
145
|
-
'
|
|
146
|
-
'
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
'
|
|
151
|
-
'
|
|
152
|
-
'
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
'number.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
'
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
'
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
'
|
|
170
|
-
'
|
|
171
|
-
'
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
'
|
|
175
|
-
'
|
|
176
|
-
'
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
'pattern.
|
|
180
|
-
'pattern.
|
|
181
|
-
'pattern.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
'
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
'
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
//
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
dsl
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
//
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
|
351
|
-
|
|
352
|
-
| `
|
|
353
|
-
| `
|
|
354
|
-
| `
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
|
363
|
-
|
|
364
|
-
| `string.
|
|
365
|
-
| `string.
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
|
374
|
-
|
|
375
|
-
| `number.
|
|
376
|
-
| `number.
|
|
377
|
-
| `number.
|
|
378
|
-
| `number.
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
|
387
|
-
|
|
388
|
-
| `format.
|
|
389
|
-
| `format.
|
|
390
|
-
| `format.
|
|
391
|
-
| `format.
|
|
392
|
-
| `format.
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
|
401
|
-
|
|
402
|
-
| `pattern.
|
|
403
|
-
| `pattern.
|
|
404
|
-
| `pattern.
|
|
405
|
-
| `pattern.
|
|
406
|
-
| `pattern.
|
|
407
|
-
| `pattern.
|
|
408
|
-
| `pattern.
|
|
409
|
-
| `pattern.
|
|
410
|
-
| `pattern.
|
|
411
|
-
| `pattern.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
|
424
|
-
|
|
425
|
-
| `{{#
|
|
426
|
-
| `{{#
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
1
|
+
# 添加自定义语言包指南
|
|
2
|
+
|
|
3
|
+
**版本**: v2.0.0-beta.1
|
|
4
|
+
**最后更新**: 2026-04-30
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📖 概述
|
|
9
|
+
|
|
10
|
+
本指南将教你如何为 schema-dsl 添加自定义语言包或扩展现有语言。
|
|
11
|
+
|
|
12
|
+
> **Node.js 要求**:`>=18.0.0`
|
|
13
|
+
>
|
|
14
|
+
> **目录加载(Node >=18)默认支持的语言文件格式**:`.js`(CommonJS)、`.cjs`、`.json`、`.jsonc`、`.json5`。
|
|
15
|
+
> **推荐**:如果你的应用是 `type: module` / ESM 项目,优先使用 `.cjs`、`.json`、`.jsonc`、`.json5`。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🏗️ 多人协作:子目录拆分语言包(v1.2.3 新增)⭐
|
|
20
|
+
|
|
21
|
+
> **适用场景**:多人/多模块开发,避免所有语言 key 堆在同一文件产生 Git 冲突和 code 码冲突。
|
|
22
|
+
|
|
23
|
+
### 目录结构
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
project/
|
|
27
|
+
├── locales/
|
|
28
|
+
│ ├── core/ # 公共 code 段:1000-1999(框架层维护)
|
|
29
|
+
│ │ ├── zh-CN.cjs
|
|
30
|
+
│ │ └── en-US.jsonc
|
|
31
|
+
│ ├── account/ # 账户模块 code 段:10000-10999(开发者A)
|
|
32
|
+
│ │ ├── zh-CN.cjs
|
|
33
|
+
│ │ └── en-US.jsonc
|
|
34
|
+
│ ├── order/ # 订单模块 code 段:20000-20999(开发者B)
|
|
35
|
+
│ │ ├── zh-CN.json5
|
|
36
|
+
│ │ └── en-US.json5
|
|
37
|
+
│ └── payment/ # 支付模块 code 段:30000-30999(开发者C)
|
|
38
|
+
│ ├── zh-CN.cjs
|
|
39
|
+
│ └── en-US.cjs
|
|
40
|
+
└── app.js
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 每个模块独立维护自己的语言文件
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
// locales/account/zh-CN.cjs — 开发者A 独立维护,互不干扰
|
|
47
|
+
module.exports = {
|
|
48
|
+
'account.notFound': { code: 10001, message: '账户不存在' },
|
|
49
|
+
'account.locked': { code: 10002, message: '账户已锁定' },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// locales/order/zh-CN.json5 — 开发者B 独立维护
|
|
53
|
+
const orderZhCN = {
|
|
54
|
+
'order.notFound': { code: 20001, message: '订单不存在' },
|
|
55
|
+
'order.notPaid': { code: 20002, message: '订单未支付' },
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 应用启动:一行配置,自动递归合并
|
|
60
|
+
|
|
61
|
+
```javascript
|
|
62
|
+
// app.js
|
|
63
|
+
const { dsl, validate } = require('schema-dsl');
|
|
64
|
+
const path = require('path');
|
|
65
|
+
|
|
66
|
+
// 自动递归扫描 locales/ 下所有子目录,同语言文件合并为一个完整语言包
|
|
67
|
+
dsl.config({
|
|
68
|
+
i18n: path.join(__dirname, 'locales')
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> - 子目录名(`account/`、`order/`)仅作为**模块组织层**,不影响最终语言 key 命名
|
|
73
|
+
> - 加载顺序:按文件系统字母序递归扫描
|
|
74
|
+
> - 同语言 key 出现重复时:默认打 `WARN` 日志,可开启严格模式阻断启动
|
|
75
|
+
|
|
76
|
+
### 严格模式:key 冲突时阻断启动(推荐 CI 环境)
|
|
77
|
+
|
|
78
|
+
```javascript
|
|
79
|
+
dsl.config({
|
|
80
|
+
i18n: path.join(__dirname, 'locales'),
|
|
81
|
+
strict: true // 同名 key 冲突时直接抛 Error,防止静默覆盖
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// 冲突示例输出:
|
|
85
|
+
// Error: [schema-dsl] i18n key 冲突 in locale 'zh-CN'
|
|
86
|
+
// 冲突 key: account.notFound
|
|
87
|
+
// 来源文件: /project/locales/account/zh-CN.cjs
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Code 段划分建议
|
|
91
|
+
|
|
92
|
+
多人开发时建议在项目根目录维护一份 `locales/CODE-SEGMENTS.md`,约定各模块的 code 号段:
|
|
93
|
+
|
|
94
|
+
| 模块 | code 范围 | 负责人 |
|
|
95
|
+
|------|----------|--------|
|
|
96
|
+
| core(公共) | 1000–1999 | 框架组 |
|
|
97
|
+
| account | 10000–10999 | 开发者A |
|
|
98
|
+
| order | 20000–20999 | 开发者B |
|
|
99
|
+
| payment | 30000–30999 | 开发者C |
|
|
100
|
+
|
|
101
|
+
> `CODE-SEGMENTS.md` / `CODE-SEGMENTS.js` 等非语言文件会被自动跳过,无需担心被误加载。
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
## 🚀 快速开始
|
|
108
|
+
|
|
109
|
+
### 推荐方式:配置语言包目录(一次性加载所有语言)⭐
|
|
110
|
+
|
|
111
|
+
**正确的使用方式**:在应用启动时一次性加载所有语言包,运行时直接切换。
|
|
112
|
+
|
|
113
|
+
#### 第1步:创建语言包文件
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
#### 第1步:创建语言包文件
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# 项目结构
|
|
120
|
+
my-project/
|
|
121
|
+
├── locales/ # 语言包目录
|
|
122
|
+
│ ├── zh-CN.cjs # 中文(CommonJS / ESM 项目都稳定)
|
|
123
|
+
│ ├── en-US.jsonc # 英文(带注释 / 末尾逗号)
|
|
124
|
+
│ └── pt-BR.json5 # 葡萄牙语(JSON5 风格)
|
|
125
|
+
└── app.js
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### 第2步:定义语言包(`locales/pt-BR.json5`)
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
module.exports = {
|
|
132
|
+
// 通用验证错误
|
|
133
|
+
'required': '{{#label}} é obrigatório',
|
|
134
|
+
'type': '{{#label}} deve ser do tipo {{#expected}}',
|
|
135
|
+
'min': '{{#label}} deve ter pelo menos {{#limit}} caracteres',
|
|
136
|
+
'max': '{{#label}} não pode exceder {{#limit}} caracteres',
|
|
137
|
+
'length': '{{#label}} deve ter exatamente {{#limit}} caracteres',
|
|
138
|
+
'pattern': '{{#label}} formato inválido',
|
|
139
|
+
'enum': '{{#label}} deve ser um dos seguintes valores: {{#allowed}}',
|
|
140
|
+
|
|
141
|
+
// 格式验证
|
|
142
|
+
'format.email': '{{#label}} deve ser um e-mail válido',
|
|
143
|
+
'format.url': '{{#label}} deve ser uma URL válida',
|
|
144
|
+
'format.uuid': '{{#label}} deve ser um UUID válido',
|
|
145
|
+
'format.date': '{{#label}} deve ser uma data válida (YYYY-MM-DD)',
|
|
146
|
+
'format.datetime': '{{#label}} deve ser uma data/hora válida (ISO 8601)',
|
|
147
|
+
|
|
148
|
+
// 字符串验证
|
|
149
|
+
'string.minLength': '{{#label}} deve ter pelo menos {{#limit}} caracteres',
|
|
150
|
+
'string.maxLength': '{{#label}} não pode exceder {{#limit}} caracteres',
|
|
151
|
+
'string.pattern': '{{#label}} formato inválido',
|
|
152
|
+
'string.alphanum': '{{#label}} deve conter apenas letras e números',
|
|
153
|
+
|
|
154
|
+
// 数字验证
|
|
155
|
+
'number.base': '{{#label}} deve ser um número',
|
|
156
|
+
'number.min': '{{#label}} não pode ser menor que {{#limit}}',
|
|
157
|
+
'number.max': '{{#label}} não pode ser maior que {{#limit}}',
|
|
158
|
+
'number.integer': '{{#label}} deve ser um inteiro',
|
|
159
|
+
'number.positive': '{{#label}} deve ser um número positivo',
|
|
160
|
+
'number.negative': '{{#label}} deve ser um número negativo',
|
|
161
|
+
|
|
162
|
+
// 布尔验证
|
|
163
|
+
'boolean.base': '{{#label}} deve ser um booleano',
|
|
164
|
+
|
|
165
|
+
// 对象验证
|
|
166
|
+
'object.base': '{{#label}} deve ser um objeto',
|
|
167
|
+
|
|
168
|
+
// 数组验证
|
|
169
|
+
'array.base': '{{#label}} deve ser um array',
|
|
170
|
+
'array.min': '{{#label}} deve ter pelo menos {{#limit}} itens',
|
|
171
|
+
'array.max': '{{#label}} não pode ter mais de {{#limit}} itens',
|
|
172
|
+
|
|
173
|
+
// 日期验证
|
|
174
|
+
'date.base': '{{#label}} deve ser uma data válida',
|
|
175
|
+
'date.min': '{{#label}} não pode ser anterior a {{#limit}}',
|
|
176
|
+
'date.max': '{{#label}} não pode ser posterior a {{#limit}}',
|
|
177
|
+
|
|
178
|
+
// 自定义模式
|
|
179
|
+
'pattern.phone.cn': 'Número de telefone inválido',
|
|
180
|
+
'pattern.idCard.cn': 'Número de identidade inválido',
|
|
181
|
+
'pattern.creditCard': 'Número de cartão de crédito inválido',
|
|
182
|
+
'pattern.objectId': 'ObjectId inválido',
|
|
183
|
+
'pattern.hexColor': 'Código de cor hexadecimal inválido',
|
|
184
|
+
'pattern.macAddress': 'Endereço MAC inválido',
|
|
185
|
+
'pattern.cron': 'Expressão Cron inválida',
|
|
186
|
+
'pattern.slug': 'Slug deve conter apenas letras minúsculas, números e hífens'
|
|
187
|
+
};
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### 第3步:应用启动时一次性加载所有语言
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const { dsl, validate } = require('schema-dsl');
|
|
194
|
+
const path = require('path');
|
|
195
|
+
|
|
196
|
+
// ========== 应用启动时配置(只执行一次)==========
|
|
197
|
+
dsl.config({
|
|
198
|
+
i18n: path.join(__dirname, 'locales') // 自动加载目录下所有语言文件
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// 说明:
|
|
202
|
+
// 1. 自动扫描 locales/ 目录下的 `.js`(CommonJS)、`.cjs`、`.json`、`.jsonc`、`.json5`
|
|
203
|
+
// 2. 从文件名提取语言代码(如 pt-BR.cjs → pt-BR)
|
|
204
|
+
// 3. 自动加载并注册所有语言包
|
|
205
|
+
// 4. 用户自定义的语言包会与系统默认语言包合并,用户的优先
|
|
206
|
+
|
|
207
|
+
// ========== 运行时直接切换语言(无需重新加载)==========
|
|
208
|
+
const schema = dsl({ username: 'string:3-32!' });
|
|
209
|
+
|
|
210
|
+
// 使用葡萄牙语
|
|
211
|
+
const result1 = validate(schema, { username: 'ab' }, { locale: 'pt-BR' });
|
|
212
|
+
// 错误消息: "username deve ter pelo menos 3 caracteres"
|
|
213
|
+
|
|
214
|
+
// 使用中文
|
|
215
|
+
const result2 = validate(schema, { username: 'ab' }, { locale: 'zh-CN' });
|
|
216
|
+
// 错误消息: "username长度不能少于3个字符"
|
|
217
|
+
|
|
218
|
+
// 使用英文
|
|
219
|
+
const result3 = validate(schema, { username: 'ab' }, { locale: 'en-US' });
|
|
220
|
+
// 错误消息: "username length must be at least 3"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### 语言包合并策略
|
|
224
|
+
|
|
225
|
+
```javascript
|
|
226
|
+
// 系统内置的 zh-CN 语言包
|
|
227
|
+
const systemZhCN = {
|
|
228
|
+
'required': '{{#label}}是必填项',
|
|
229
|
+
'string.minLength': '{{#label}}长度不能少于{{#limit}}个字符'
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// 用户自定义的 locales/zh-CN.cjs
|
|
233
|
+
const userZhCN = {
|
|
234
|
+
'required': '{{#label}}必须填写', // 覆盖系统默认
|
|
235
|
+
'custom.myError': '自定义错误' // 新增自定义消息
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// 最终合并结果(深度合并)
|
|
239
|
+
const finalZhCN = {
|
|
240
|
+
'required': '{{#label}}必须填写', // ✅ 用户的优先
|
|
241
|
+
'string.minLength': '{{#label}}长度不能少于{{#limit}}个字符', // 保留系统默认
|
|
242
|
+
'custom.myError': '自定义错误' // 新增自定义消息
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
### 方式2:直接传入对象(适合动态配置)
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
const { dsl } = require('schema-dsl');
|
|
252
|
+
|
|
253
|
+
// 应用启动时配置
|
|
254
|
+
dsl.config({
|
|
255
|
+
i18n: {
|
|
256
|
+
'pt-BR': require('./locales/pt-BR'),
|
|
257
|
+
'de-DE': require('./locales/de-DE'),
|
|
258
|
+
'ko-KR': require('./locales/ko-KR')
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
// 运行时直接切换
|
|
263
|
+
validate(schema, data, { locale: 'pt-BR' });
|
|
264
|
+
validate(schema, data, { locale: 'de-DE' });
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## ⚠️ 错误示例(不推荐)
|
|
270
|
+
|
|
271
|
+
### ❌ 错误:运行时单个加载语言包
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
const { Locale } = require('schema-dsl');
|
|
275
|
+
|
|
276
|
+
// ❌ 不推荐:在每次验证前动态加载
|
|
277
|
+
function validateUser(data, locale) {
|
|
278
|
+
if (locale === 'pt-BR') {
|
|
279
|
+
Locale.addLocale('pt-BR', require('./locales/pt-BR')); // 每次都加载,性能差
|
|
280
|
+
}
|
|
281
|
+
return validate(schema, data, { locale });
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
```javascript
|
|
286
|
+
// ✅ 正确:应用启动时一次性加载
|
|
287
|
+
// app.js 启动入口
|
|
288
|
+
dsl.config({ i18n: './locales' }); // 只加载一次
|
|
289
|
+
|
|
290
|
+
// 运行时直接切换,无需重新加载
|
|
291
|
+
function validateUser(data, locale) {
|
|
292
|
+
return validate(schema, data, { locale }); // ✅ 直接切换,性能好
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 为什么推荐"首次加载,运行时切换"?
|
|
297
|
+
|
|
298
|
+
| 方式 | 加载次数 | 性能 | 内存 | 推荐度 |
|
|
299
|
+
|------|---------|------|------|--------|
|
|
300
|
+
| **首次加载所有** | 1次 | ⭐⭐⭐⭐⭐ 极快 | 低 | ✅ 强烈推荐 |
|
|
301
|
+
| 运行时单个加载 | N次 | ⭐⭐ 慢 | 中 | ❌ 不推荐 |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 🎯 完整示例
|
|
306
|
+
|
|
307
|
+
```javascript
|
|
308
|
+
// ========== app.js(应用启动入口)==========
|
|
309
|
+
const express = require('express');
|
|
310
|
+
const { dsl, validate } = require('schema-dsl');
|
|
311
|
+
const path = require('path');
|
|
312
|
+
|
|
313
|
+
// 应用启动时一次性加载所有语言包
|
|
314
|
+
dsl.config({
|
|
315
|
+
i18n: path.join(__dirname, 'locales')
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
const app = express();
|
|
319
|
+
|
|
320
|
+
// ========== routes/user.js(业务路由)==========
|
|
321
|
+
const userSchema = dsl({
|
|
322
|
+
username: 'string:3-32!',
|
|
323
|
+
email: 'email!',
|
|
324
|
+
age: 'number:18-120'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
app.post('/api/users', (req, res) => {
|
|
328
|
+
// 从请求头获取用户语言偏好
|
|
329
|
+
const locale = req.headers['accept-language']?.split(',')[0]?.trim() || 'en-US';
|
|
330
|
+
|
|
331
|
+
// 验证(直接切换语言,无需加载)
|
|
332
|
+
const result = validate(userSchema, req.body, { locale });
|
|
333
|
+
|
|
334
|
+
if (!result.valid) {
|
|
335
|
+
return res.status(400).json({
|
|
336
|
+
errors: result.errors // 自动使用用户偏好的语言
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// 处理请求...
|
|
341
|
+
});
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## 📋 完整的消息键列表
|
|
347
|
+
|
|
348
|
+
### 通用键
|
|
349
|
+
|
|
350
|
+
| 键名 | 说明 | 示例 |
|
|
351
|
+
|-----|------|------|
|
|
352
|
+
| `required` | 必填字段 | `{{#label}} é obrigatório` |
|
|
353
|
+
| `type` | 类型错误 | `{{#label}} deve ser do tipo {{#expected}}` |
|
|
354
|
+
| `min` | 最小长度(通用) | `{{#label}} deve ter pelo menos {{#limit}} caracteres` |
|
|
355
|
+
| `max` | 最大长度(通用) | `{{#label}} não pode exceder {{#limit}} caracteres` |
|
|
356
|
+
| `length` | 精确长度 | `{{#label}} deve ter exatamente {{#limit}} caracteres` |
|
|
357
|
+
| `pattern` | 模式匹配 | `{{#label}} formato inválido` |
|
|
358
|
+
| `enum` | 枚举值 | `{{#label}} deve ser um dos seguintes: {{#allowed}}` |
|
|
359
|
+
|
|
360
|
+
### 字符串验证键
|
|
361
|
+
|
|
362
|
+
| 键名 | 说明 | 可用变量 |
|
|
363
|
+
|-----|------|---------|
|
|
364
|
+
| `string.minLength` | 最小长度 | `{{#label}}`, `{{#limit}}` |
|
|
365
|
+
| `string.maxLength` | 最大长度 | `{{#label}}`, `{{#limit}}` |
|
|
366
|
+
| `string.length` | 精确长度 | `{{#label}}`, `{{#limit}}` |
|
|
367
|
+
| `string.pattern` | 模式匹配 | `{{#label}}` |
|
|
368
|
+
| `string.alphanum` | 字母数字 | `{{#label}}` |
|
|
369
|
+
| `string.enum` | 枚举值 | `{{#label}}`, `{{#valids}}` |
|
|
370
|
+
|
|
371
|
+
### 数字验证键
|
|
372
|
+
|
|
373
|
+
| 键名 | 说明 | 可用变量 |
|
|
374
|
+
|-----|------|---------|
|
|
375
|
+
| `number.base` | 类型错误 | `{{#label}}` |
|
|
376
|
+
| `number.min` | 最小值 | `{{#label}}`, `{{#limit}}` |
|
|
377
|
+
| `number.max` | 最大值 | `{{#label}}`, `{{#limit}}` |
|
|
378
|
+
| `number.integer` | 整数 | `{{#label}}` |
|
|
379
|
+
| `number.positive` | 正数 | `{{#label}}` |
|
|
380
|
+
| `number.negative` | 负数 | `{{#label}}` |
|
|
381
|
+
| `number.precision` | 小数精度 | `{{#label}}`, `{{#limit}}` |
|
|
382
|
+
| `number.port` | 端口号 | `{{#label}}` |
|
|
383
|
+
|
|
384
|
+
### 格式验证键
|
|
385
|
+
|
|
386
|
+
| 键名 | 说明 |
|
|
387
|
+
|-----|------|
|
|
388
|
+
| `format.email` | 邮箱格式 |
|
|
389
|
+
| `format.url` | URL格式 |
|
|
390
|
+
| `format.uuid` | UUID格式 |
|
|
391
|
+
| `format.date` | 日期格式 |
|
|
392
|
+
| `format.datetime` | 日期时间格式 |
|
|
393
|
+
| `format.time` | 时间格式 |
|
|
394
|
+
| `format.ipv4` | IPv4地址 |
|
|
395
|
+
| `format.ipv6` | IPv6地址 |
|
|
396
|
+
| `format.binary` | Base64编码 |
|
|
397
|
+
|
|
398
|
+
### 自定义模式键
|
|
399
|
+
|
|
400
|
+
| 键名 | 说明 |
|
|
401
|
+
|-----|------|
|
|
402
|
+
| `pattern.phone.cn` | 中国手机号 |
|
|
403
|
+
| `pattern.phone.us` | 美国电话号 |
|
|
404
|
+
| `pattern.idCard.cn` | 中国身份证 |
|
|
405
|
+
| `pattern.creditCard` | 信用卡号 |
|
|
406
|
+
| `pattern.objectId` | MongoDB ObjectId |
|
|
407
|
+
| `pattern.hexColor` | 十六进制颜色 |
|
|
408
|
+
| `pattern.macAddress` | MAC地址 |
|
|
409
|
+
| `pattern.cron` | Cron表达式 |
|
|
410
|
+
| `pattern.slug` | URL别名 |
|
|
411
|
+
| `pattern.username` | 用户名 |
|
|
412
|
+
| `pattern.password.weak` | 弱密码 |
|
|
413
|
+
| `pattern.password.medium` | 中等密码 |
|
|
414
|
+
| `pattern.password.strong` | 强密码 |
|
|
415
|
+
| `pattern.password.veryStrong` | 超强密码 |
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## 🎨 模板变量
|
|
420
|
+
|
|
421
|
+
所有错误消息支持以下模板变量:
|
|
422
|
+
|
|
423
|
+
| 变量 | 说明 | 使用示例 |
|
|
424
|
+
|------|------|---------|
|
|
425
|
+
| `{{#label}}` | 字段标签 | `{{#label}} é obrigatório` |
|
|
426
|
+
| `{{#limit}}` | 限制值(长度/大小) | `deve ter pelo menos {{#limit}} caracteres` |
|
|
427
|
+
| `{{#allowed}}` | 允许的值列表 | `deve ser um dos seguintes: {{#allowed}}` |
|
|
428
|
+
| `{{#expected}}` | 期望的类型 | `deve ser do tipo {{#expected}}` |
|
|
429
|
+
| `{{#valids}}` | 有效值列表(数组) | `deve ser: {{#valids}}` |
|
|
430
|
+
| `{{#path}}` | 字段路径 | `Erro no campo {{#path}}` |
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## 📚 参考内置语言包
|
|
435
|
+
|
|
436
|
+
你可以参考内置的语言包作为模板:
|
|
437
|
+
|
|
438
|
+
```javascript
|
|
439
|
+
const { Locale } = require('schema-dsl');
|
|
440
|
+
|
|
441
|
+
// 查看中文语言包
|
|
442
|
+
const zhCN = Locale.getMessages('zh-CN');
|
|
443
|
+
console.log(zhCN);
|
|
444
|
+
|
|
445
|
+
// 查看英文语言包
|
|
446
|
+
const enUS = Locale.getMessages('en-US');
|
|
447
|
+
console.log(enUS);
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
或者直接查看源码:
|
|
451
|
+
- 中文:`src/locales/zh-CN.ts`
|
|
452
|
+
- 英文:`src/locales/en-US.ts`
|
|
453
|
+
- 日语:`src/locales/ja-JP.ts`
|
|
454
|
+
- 西班牙语:`src/locales/es-ES.ts`
|
|
455
|
+
- 法语:`src/locales/fr-FR.ts`
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## ✅ 最佳实践
|
|
460
|
+
|
|
461
|
+
1. **完整性**:确保翻译所有常用的错误消息键
|
|
462
|
+
2. **一致性**:保持错误消息风格统一
|
|
463
|
+
3. **模板变量**:正确使用 `{{#label}}`、`{{#limit}}` 等变量
|
|
464
|
+
4. **测试**:添加语言包后进行测试,确保所有消息正确显示
|
|
465
|
+
5. **文档**:为自定义语言包编写使用说明
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 🤝 贡献语言包
|
|
470
|
+
|
|
471
|
+
如果你为 schema-dsl 添加了新语言包,欢迎提交 Pull Request:
|
|
472
|
+
|
|
473
|
+
1. Fork 项目
|
|
474
|
+
2. 在 `src/locales/` 目录创建新语言文件(如 `pt-BR.ts`)
|
|
475
|
+
3. 完整翻译所有消息键
|
|
476
|
+
4. 在 `src/locales/index.ts` 中注册新语言
|
|
477
|
+
5. 添加测试用例(在 `test/unit/locales/` 目录)
|
|
478
|
+
6. 提交 Pull Request
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## 📞 支持
|
|
483
|
+
|
|
484
|
+
如果你在添加语言包时遇到问题:
|
|
485
|
+
|
|
486
|
+
- 查看 [多语言配置指南](./i18n.md)
|
|
487
|
+
- 查看 [动态多语言配置指南](./dynamic-locale.md)
|
|
488
|
+
- 提交 Issue: https://github.com/vextjs/schema-dsl/issues
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## 对应示例文件
|
|
493
|
+
|
|
494
|
+
**示例入口**: [add-custom-locale.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/add-custom-locale.ts)
|
|
495
|
+
**说明**: 覆盖 `Locale.addLocale()` 注册新语言、读取消息文本,以及在自定义 locale 下执行验证的最小工作流。
|
|
496
|
+
|