schema-dsl 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/.eslintignore +10 -0
  2. package/.eslintrc.json +27 -0
  3. package/.github/CODE_OF_CONDUCT.md +45 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +57 -0
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +45 -0
  7. package/.github/ISSUE_TEMPLATE/question.md +31 -0
  8. package/.github/PULL_REQUEST_TEMPLATE.md +70 -0
  9. package/.github/SECURITY.md +184 -0
  10. package/.github/workflows/ci.yml +35 -0
  11. package/CHANGELOG.md +633 -0
  12. package/CONTRIBUTING.md +368 -0
  13. package/LICENSE +21 -0
  14. package/README.md +1122 -0
  15. package/STATUS.md +273 -0
  16. package/docs/FEATURE-INDEX.md +521 -0
  17. package/docs/INDEX.md +224 -0
  18. package/docs/api-reference.md +1098 -0
  19. package/docs/best-practices.md +672 -0
  20. package/docs/cache-manager.md +336 -0
  21. package/docs/design-philosophy.md +602 -0
  22. package/docs/dsl-syntax.md +654 -0
  23. package/docs/dynamic-locale.md +552 -0
  24. package/docs/error-handling.md +703 -0
  25. package/docs/export-guide.md +459 -0
  26. package/docs/faq.md +576 -0
  27. package/docs/frontend-i18n-guide.md +290 -0
  28. package/docs/i18n-user-guide.md +488 -0
  29. package/docs/label-vs-description.md +262 -0
  30. package/docs/markdown-exporter.md +398 -0
  31. package/docs/mongodb-exporter.md +279 -0
  32. package/docs/multi-type-support.md +319 -0
  33. package/docs/mysql-exporter.md +257 -0
  34. package/docs/plugin-system.md +542 -0
  35. package/docs/postgresql-exporter.md +290 -0
  36. package/docs/quick-start.md +761 -0
  37. package/docs/schema-helper.md +340 -0
  38. package/docs/schema-utils.md +492 -0
  39. package/docs/string-extensions.md +480 -0
  40. package/docs/troubleshooting.md +471 -0
  41. package/docs/type-converter.md +319 -0
  42. package/docs/type-reference.md +219 -0
  43. package/docs/validate.md +486 -0
  44. package/docs/validation-guide.md +484 -0
  45. package/examples/array-dsl-example.js +227 -0
  46. package/examples/custom-extension.js +85 -0
  47. package/examples/dsl-match-example.js +74 -0
  48. package/examples/dsl-style.js +118 -0
  49. package/examples/dynamic-locale-configuration.js +348 -0
  50. package/examples/dynamic-locale-example.js +287 -0
  51. package/examples/export-demo.js +130 -0
  52. package/examples/i18n-full-demo.js +310 -0
  53. package/examples/i18n-memory-safety.examples.js +268 -0
  54. package/examples/markdown-export.js +71 -0
  55. package/examples/middleware-usage.js +93 -0
  56. package/examples/password-reset/README.md +153 -0
  57. package/examples/password-reset/schema.js +26 -0
  58. package/examples/password-reset/test.js +101 -0
  59. package/examples/plugin-system.examples.js +205 -0
  60. package/examples/simple-example.js +122 -0
  61. package/examples/string-extensions.js +297 -0
  62. package/examples/user-registration/README.md +156 -0
  63. package/examples/user-registration/routes.js +92 -0
  64. package/examples/user-registration/schema.js +150 -0
  65. package/examples/user-registration/server.js +74 -0
  66. package/index.d.ts +1999 -0
  67. package/index.js +270 -0
  68. package/index.mjs +30 -0
  69. package/lib/adapters/DslAdapter.js +653 -0
  70. package/lib/adapters/index.js +20 -0
  71. package/lib/config/constants.js +286 -0
  72. package/lib/config/patterns/creditCard.js +9 -0
  73. package/lib/config/patterns/idCard.js +9 -0
  74. package/lib/config/patterns/index.js +8 -0
  75. package/lib/config/patterns/licensePlate.js +4 -0
  76. package/lib/config/patterns/passport.js +4 -0
  77. package/lib/config/patterns/phone.js +9 -0
  78. package/lib/config/patterns/postalCode.js +5 -0
  79. package/lib/core/CacheManager.js +376 -0
  80. package/lib/core/DslBuilder.js +740 -0
  81. package/lib/core/ErrorCodes.js +233 -0
  82. package/lib/core/ErrorFormatter.js +342 -0
  83. package/lib/core/JSONSchemaCore.js +347 -0
  84. package/lib/core/Locale.js +119 -0
  85. package/lib/core/MessageTemplate.js +89 -0
  86. package/lib/core/PluginManager.js +448 -0
  87. package/lib/core/StringExtensions.js +209 -0
  88. package/lib/core/Validator.js +316 -0
  89. package/lib/exporters/MarkdownExporter.js +420 -0
  90. package/lib/exporters/MongoDBExporter.js +162 -0
  91. package/lib/exporters/MySQLExporter.js +212 -0
  92. package/lib/exporters/PostgreSQLExporter.js +289 -0
  93. package/lib/exporters/index.js +24 -0
  94. package/lib/locales/en-US.js +65 -0
  95. package/lib/locales/es-ES.js +66 -0
  96. package/lib/locales/fr-FR.js +66 -0
  97. package/lib/locales/index.js +8 -0
  98. package/lib/locales/ja-JP.js +66 -0
  99. package/lib/locales/zh-CN.js +93 -0
  100. package/lib/utils/LRUCache.js +174 -0
  101. package/lib/utils/SchemaHelper.js +240 -0
  102. package/lib/utils/SchemaUtils.js +313 -0
  103. package/lib/utils/TypeConverter.js +245 -0
  104. package/lib/utils/index.js +13 -0
  105. package/lib/validators/CustomKeywords.js +203 -0
  106. package/lib/validators/index.js +11 -0
  107. package/package.json +70 -0
  108. package/plugins/custom-format.js +101 -0
  109. package/plugins/custom-validator.js +200 -0
@@ -0,0 +1,486 @@
1
+ # validate 方法详细文档
2
+
3
+ ## 📑 目录
4
+
5
+ ### 基础概念
6
+ - [概述](#概述) - validate 方法介绍
7
+ - [方法签名](#方法签名) - API 定义
8
+
9
+ ### 参数详解
10
+ - [参数详解](#参数详解)
11
+ - [schema 参数](#schema-参数)
12
+ - [options 对象属性](#options-对象属性)
13
+ - [返回值详解](#返回值详解)
14
+ - [valid (Boolean)](#valid-boolean)
15
+ - [errors (Array)](#errors-array)
16
+ - [data (Any)](#data-any)
17
+
18
+ ### 使用示例
19
+ - [基础示例](#基础示例)
20
+ - [示例 1: 验证简单对象](#示例-1-验证简单对象)
21
+ - [示例 2: 验证复杂对象](#示例-2-验证复杂对象)
22
+ - [示例 3: 处理验证错误](#示例-3-处理验证错误)
23
+ - [示例 4: 使用默认值](#示例-4-使用默认值)
24
+
25
+ ### 高级功能
26
+ - [高级用法](#高级用法)
27
+ - [批量验证](#批量验证)
28
+ - [自定义错误格式](#自定义错误格式)
29
+ - [性能优化](#性能优化)
30
+
31
+ ### 参考资料
32
+ - [相关文档](#相关文档)
33
+ - [API 参考](#api-参考)
34
+
35
+ ---
36
+
37
+ ## 概述
38
+
39
+ `validate` 是 Validator 类的核心方法,用于验证数据是否符合 JSON Schema 定义。基于高性能的 ajv 验证器实现。
40
+
41
+ ---
42
+
43
+ ## 方法签名
44
+
45
+ ```javascript
46
+ validator.validate(schema, data, options = {})
47
+ ```
48
+
49
+ **参数说明**:
50
+ - `schema` (Object|Function): JSON Schema 对象或已编译的验证函数
51
+ - `data` (Any): 待验证的数据
52
+ - `options` (Object): 验证选项(可选)
53
+
54
+ **返回值**:
55
+ ```javascript
56
+ {
57
+ valid: Boolean, // 是否有效
58
+ errors: Array, // 错误列表
59
+ data: Any // 验证后的数据(可能被 useDefaults 修改)
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## 参数详解
66
+
67
+ ### schema 参数
68
+
69
+ JSON Schema 对象,支持 JSON Schema Draft 7 标准。
70
+
71
+ | 参数类型 | 说明 | 来源 |
72
+ |---------|------|------|
73
+ | Object | JSON Schema 对象 | JSON Schema 标准 ✅ |
74
+ | Function | 已编译的验证函数(通过 `compile()` 生成) | ajv ✅ |
75
+
76
+ ### options 对象属性
77
+
78
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
79
+ |------|------|------|--------|------|
80
+ | `format` | Boolean | 否 | `true` | 是否格式化错误信息 |
81
+
82
+ **图例说明**:
83
+ - ✅ **标准功能**: 该参数来自 JSON Schema 或 ajv 标准
84
+
85
+ ---
86
+
87
+ ## 返回值详解
88
+
89
+ ### valid (Boolean)
90
+
91
+ 表示数据是否通过验证。
92
+
93
+ ```javascript
94
+ result.valid === true // 验证通过
95
+ result.valid === false // 验证失败
96
+ ```
97
+
98
+ ### errors (Array)
99
+
100
+ 验证错误列表,当 `valid` 为 `false` 时包含详细错误信息。
101
+
102
+ **错误对象结构**:
103
+ ```javascript
104
+ {
105
+ path: String, // 错误字段路径,如 'user.email'
106
+ message: String, // 错误描述信息
107
+ keyword: String, // 触发的 Schema 关键字
108
+ params: Object // 错误相关参数
109
+ }
110
+ ```
111
+
112
+ ### data (Any)
113
+
114
+ 验证后的数据。如果 Validator 配置了 `useDefaults: true`,则会应用 Schema 中定义的默认值。
115
+
116
+ ---
117
+
118
+ ## 基础示例
119
+
120
+ ### 示例 1: 验证简单对象
121
+
122
+ ```javascript
123
+ const { Validator } = require('schema-dsl');
124
+
125
+ const validator = new Validator();
126
+
127
+ const schema = {
128
+ type: 'object',
129
+ properties: {
130
+ name: { type: 'string' },
131
+ age: { type: 'number' }
132
+ },
133
+ required: ['name']
134
+ };
135
+
136
+ const result = validator.validate(schema, {
137
+ name: 'John',
138
+ age: 25
139
+ });
140
+
141
+ console.log(result.valid); // true
142
+ console.log(result.errors); // []
143
+ ```
144
+
145
+ ### 示例 2: 处理验证失败
146
+
147
+ ```javascript
148
+ const result = validator.validate(schema, {
149
+ age: 'invalid'
150
+ });
151
+
152
+ console.log(result.valid); // false
153
+ console.log(result.errors);
154
+ // [
155
+ // { path: '', message: "must have required property 'name'" },
156
+ // { path: 'age', message: 'must be number' }
157
+ // ]
158
+ ```
159
+
160
+ ---
161
+
162
+ ## 高级示例
163
+
164
+ ### 示例 3: 验证字符串约束
165
+
166
+ ```javascript
167
+ const schema = {
168
+ type: 'string',
169
+ minLength: 3,
170
+ maxLength: 32,
171
+ pattern: '^[a-zA-Z0-9]+$'
172
+ };
173
+
174
+ // 有效数据
175
+ console.log(validator.validate(schema, 'john123').valid); // true
176
+
177
+ // 太短
178
+ console.log(validator.validate(schema, 'ab').valid); // false
179
+
180
+ // 包含非法字符
181
+ console.log(validator.validate(schema, 'john-123').valid); // false
182
+ ```
183
+
184
+ ### 示例 4: 验证数字范围
185
+
186
+ ```javascript
187
+ const schema = {
188
+ type: 'number',
189
+ minimum: 0,
190
+ maximum: 100
191
+ };
192
+
193
+ console.log(validator.validate(schema, 50).valid); // true
194
+ console.log(validator.validate(schema, -1).valid); // false
195
+ console.log(validator.validate(schema, 101).valid); // false
196
+ ```
197
+
198
+ ### 示例 5: 验证邮箱格式
199
+
200
+ ```javascript
201
+ const schema = {
202
+ type: 'string',
203
+ format: 'email'
204
+ };
205
+
206
+ console.log(validator.validate(schema, 'test@example.com').valid); // true
207
+ console.log(validator.validate(schema, 'invalid-email').valid); // false
208
+ ```
209
+
210
+ ### 示例 6: 验证枚举值
211
+
212
+ ```javascript
213
+ const schema = {
214
+ type: 'string',
215
+ enum: ['active', 'inactive', 'pending']
216
+ };
217
+
218
+ console.log(validator.validate(schema, 'active').valid); // true
219
+ console.log(validator.validate(schema, 'invalid').valid); // false
220
+ ```
221
+
222
+ ### 示例 7: 验证嵌套对象
223
+
224
+ ```javascript
225
+ const schema = {
226
+ type: 'object',
227
+ properties: {
228
+ user: {
229
+ type: 'object',
230
+ properties: {
231
+ name: { type: 'string' },
232
+ email: { type: 'string', format: 'email' }
233
+ },
234
+ required: ['name', 'email']
235
+ }
236
+ }
237
+ };
238
+
239
+ const data = {
240
+ user: {
241
+ name: 'John',
242
+ email: 'john@example.com'
243
+ }
244
+ };
245
+
246
+ const result = validator.validate(schema, data);
247
+ console.log(result.valid); // true
248
+ ```
249
+
250
+ ### 示例 8: 验证数组
251
+
252
+ ```javascript
253
+ const schema = {
254
+ type: 'array',
255
+ items: { type: 'string' },
256
+ minItems: 1,
257
+ maxItems: 10
258
+ };
259
+
260
+ console.log(validator.validate(schema, ['a', 'b', 'c']).valid); // true
261
+ console.log(validator.validate(schema, []).valid); // false (minItems)
262
+ console.log(validator.validate(schema, [1, 2, 3]).valid); // false (type)
263
+ ```
264
+
265
+ ---
266
+
267
+ ## 使用默认值
268
+
269
+ 当 Validator 配置了 `useDefaults: true` 时,会自动应用 Schema 中的默认值。
270
+
271
+ ```javascript
272
+ const validator = new Validator({ useDefaults: true });
273
+
274
+ const schema = {
275
+ type: 'object',
276
+ properties: {
277
+ name: { type: 'string' },
278
+ status: { type: 'string', default: 'active' }
279
+ }
280
+ };
281
+
282
+ const result = validator.validate(schema, { name: 'John' });
283
+
284
+ console.log(result.valid); // true
285
+ console.log(result.data); // { name: 'John', status: 'active' }
286
+ console.log(result.data.status); // 'active' (自动应用默认值)
287
+ ```
288
+
289
+ ---
290
+
291
+ ## 使用已编译的验证函数
292
+
293
+ 为了提高性能,可以先编译 Schema,然后重复使用编译后的验证函数。
294
+
295
+ ```javascript
296
+ // 编译 Schema
297
+ const validateFn = validator.compile(schema);
298
+
299
+ // 重复使用(性能更好)
300
+ const result1 = validator.validate(validateFn, data1);
301
+ const result2 = validator.validate(validateFn, data2);
302
+ const result3 = validator.validate(validateFn, data3);
303
+ ```
304
+
305
+ ---
306
+
307
+ ## 错误处理最佳实践
308
+
309
+ ### 实践 1: 展示用户友好的错误信息
310
+
311
+ ```javascript
312
+ const result = validator.validate(schema, data);
313
+
314
+ if (!result.valid) {
315
+ // 格式化错误信息
316
+ result.errors.forEach(err => {
317
+ console.log(`字段 "${err.path}": ${err.message}`);
318
+ });
319
+
320
+ // 或者整体提示
321
+ console.log(`验证失败,共 ${result.errors.length} 个错误`);
322
+ }
323
+ ```
324
+
325
+ ### 实践 2: API 响应中返回错误
326
+
327
+ ```javascript
328
+ const result = validator.validate(schema, req.body);
329
+
330
+ if (!result.valid) {
331
+ return res.status(400).json({
332
+ success: false,
333
+ message: '数据验证失败',
334
+ errors: result.errors.map(err => ({
335
+ field: err.path,
336
+ message: err.message
337
+ }))
338
+ });
339
+ }
340
+
341
+ // 验证通过,继续处理
342
+ processData(result.data);
343
+ ```
344
+
345
+ ### 实践 3: 抛出异常
346
+
347
+ ```javascript
348
+ const result = validator.validate(schema, data);
349
+
350
+ if (!result.valid) {
351
+ const error = new ValidationError('数据验证失败');
352
+ error.errors = result.errors;
353
+ throw error;
354
+ }
355
+ ```
356
+
357
+ ---
358
+
359
+ ## 性能优化建议
360
+
361
+ ### 建议 1: 复用 Validator 实例
362
+
363
+ ```javascript
364
+ // ✅ 好:复用实例
365
+ const validator = new Validator();
366
+
367
+ app.post('/api/users', (req, res) => {
368
+ const result = validator.validate(userSchema, req.body);
369
+ // ...
370
+ });
371
+
372
+ // ❌ 不好:每次创建新实例
373
+ app.post('/api/users', (req, res) => {
374
+ const validator = new Validator(); // 不推荐
375
+ const result = validator.validate(userSchema, req.body);
376
+ // ...
377
+ });
378
+ ```
379
+
380
+ ### 建议 2: 预编译 Schema
381
+
382
+ ```javascript
383
+ // 应用启动时预编译
384
+ const validateUser = validator.compile(userSchema);
385
+ const validateProduct = validator.compile(productSchema);
386
+
387
+ // 使用时直接验证(更快)
388
+ app.post('/api/users', (req, res) => {
389
+ const result = validator.validate(validateUser, req.body);
390
+ // ...
391
+ });
392
+ ```
393
+
394
+ ### 建议 3: 使用缓存
395
+
396
+ ```javascript
397
+ // 使用缓存键
398
+ const result = validator.validate(
399
+ schema,
400
+ data,
401
+ { cacheKey: 'user-schema' } // 自动缓存编译结果
402
+ );
403
+ ```
404
+
405
+ ---
406
+
407
+ ## 常见问题
408
+
409
+ ### Q1: 如何验证可选字段?
410
+
411
+ 不在 `required` 数组中的字段自动为可选:
412
+
413
+ ```javascript
414
+ const schema = {
415
+ type: 'object',
416
+ properties: {
417
+ name: { type: 'string' },
418
+ age: { type: 'number' } // age 是可选的
419
+ },
420
+ required: ['name'] // 只有 name 是必填的
421
+ };
422
+ ```
423
+
424
+ ### Q2: 如何允许额外字段?
425
+
426
+ JSON Schema 默认允许额外字段。如果要禁止额外字段:
427
+
428
+ ```javascript
429
+ const schema = {
430
+ type: 'object',
431
+ properties: {
432
+ name: { type: 'string' }
433
+ },
434
+ additionalProperties: false // 禁止额外字段
435
+ };
436
+ ```
437
+
438
+ ### Q3: 如何验证多种类型?
439
+
440
+ 使用 `anyOf` 或 `oneOf`:
441
+
442
+ ```javascript
443
+ const schema = {
444
+ type: 'object',
445
+ properties: {
446
+ value: {
447
+ anyOf: [
448
+ { type: 'string' },
449
+ { type: 'number' }
450
+ ]
451
+ }
452
+ }
453
+ };
454
+ ```
455
+
456
+ ### Q4: 性能如何?
457
+
458
+ 基于 ajv,业界最快的 JSON Schema 验证器:
459
+ - 验证速度 >15,000 ops/s
460
+ - 内置编译缓存
461
+ - 支持批量验证优化
462
+
463
+ ---
464
+
465
+ ## 相关文档
466
+
467
+ - [Validator 类概述](./validator.md)
468
+ - [compile 方法](./compile.md) - 编译 Schema 提升性能
469
+ - [validateBatch 方法](./validate-batch.md) - 批量验证
470
+ - [addKeyword 方法](./add-keyword.md) - 添加自定义验证
471
+ - [JSON Schema 基础](./json-schema-basics.md)
472
+
473
+ ---
474
+
475
+ ## 外部参考
476
+
477
+ - [JSON Schema 官方文档](https://json-schema.org/)
478
+ - [ajv 文档](https://ajv.js.org/)
479
+ - [JSON Schema Validator](https://www.jsonschemavalidator.net/) - 在线测试工具
480
+
481
+ ---
482
+
483
+
484
+ **最后更新**: 2025-12-24
485
+
486
+