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,761 @@
1
+ # schema-dsl 快速上手
2
+
3
+ > **阅读时间**: 5分钟
4
+ > **目标**: 快速掌握 schema-dsl 核心用法
5
+
6
+ ---
7
+
8
+ ## 📑 目录
9
+
10
+ ### 入门指南
11
+ - [🚀 安装](#-安装)
12
+ - [📖 5分钟快速入门](#-5分钟快速入门)
13
+ - [1. Hello World(30秒)](#1-hello-world30秒)
14
+ - [2. DSL 语法速查(1分钟)](#2-dsl-语法速查1分钟)
15
+ - [3. String 扩展(2分钟)](#3-string-扩展2分钟)
16
+ - [4. 完整示例(2分钟)](#4-完整示例2分钟)
17
+
18
+ ### 进阶功能
19
+ - [🔧 自定义验证](#-自定义验证)
20
+ - [🗄️ 数据库导出](#️-数据库导出)
21
+ - [📚 下一步](#-下一步)
22
+
23
+ ---
24
+
25
+ ## 🚀 安装
26
+
27
+ ```bash
28
+ npm install schema-dsl
29
+ ```
30
+
31
+ ---
32
+
33
+ ## 📖 5分钟快速入门
34
+
35
+ ### 1. Hello World(30秒)
36
+
37
+ ```javascript
38
+ const { dsl, validate } = require('schema-dsl');
39
+
40
+ // 定义Schema
41
+ const schema = dsl({
42
+ name: 'string:1-50!',
43
+ email: 'email!'
44
+ });
45
+
46
+ // 验证数据(使用便捷函数)
47
+ const result = validate(schema, {
48
+ name: '张三',
49
+ email: 'zhangsan@example.com'
50
+ });
51
+
52
+ console.log(result.valid); // true
53
+ ```
54
+
55
+ **解释**:
56
+ - `'string:1-50!'` - 必填字符串,长度1-50
57
+ - `'email!'` - 必填邮箱
58
+ - `!` 表示必填
59
+
60
+ ---
61
+
62
+ ### 2. DSL 语法速查(1分钟)
63
+
64
+ ```javascript
65
+ // 基本类型
66
+ 'string' // 字符串
67
+ 'number' // 数字
68
+ 'integer' // 整数
69
+ 'boolean' // 布尔值
70
+ 'email' // 邮箱
71
+ 'url' // URL
72
+ 'date' // 日期
73
+
74
+ // 约束
75
+ 'string:3-32' // 长度3-32(范围)
76
+ 'string:100' // 最大长度100(简写)
77
+ 'string:-100' // 最大长度100(明确写法)
78
+ 'string:10-' // 最小长度10(无最大限制)
79
+ 'number:18-120' // 范围18-120
80
+
81
+ // 必填
82
+ 'string!' // 必填字符串
83
+ 'email!' // 必填邮箱
84
+
85
+ // 枚举
86
+ 'active|inactive|pending' // 三选一
87
+
88
+ // 数组
89
+ 'array<string>' // 字符串数组
90
+ 'array:1-10<string>' // 1-10个字符串
91
+ 'array<string:1-50>' // 带约束的数组元素
92
+ ```
93
+
94
+ **语法规则**:
95
+ - `type:max` → 最大值(简写)
96
+ - `type:min-max` → 范围
97
+ - `type:min-` → 只限最小
98
+ - `type:-max` → 只限最大
99
+
100
+ ---
101
+
102
+ ### 3. String 扩展(2分钟)
103
+
104
+ 字符串支持链式调用:
105
+
106
+ ```javascript
107
+ const schema = dsl({
108
+ // 字符串直接链式调用,无需 dsl() 包裹
109
+ email: 'email!'
110
+ .pattern(/custom/)
111
+ .label('邮箱地址'),
112
+
113
+ username: 'string:3-32!'
114
+ .pattern(/^[a-zA-Z0-9_]+$/)
115
+ .messages({
116
+ 'pattern': '只能包含字母、数字和下划线'
117
+ })
118
+ .label('用户名'),
119
+
120
+ // 简单字段仍然可以用纯DSL
121
+ age: 'number:18-120',
122
+ role: 'user|admin'
123
+ });
124
+ ```
125
+
126
+ **可用方法**:
127
+ - `.pattern(regex)` - 正则验证
128
+ - `.label(text)` - 字段标签
129
+ - `.messages(obj)` - 自定义消息
130
+ - `.description(text)` - 描述
131
+ - `.custom(fn)` - 自定义验证器
132
+
133
+ ---
134
+
135
+ ### 4. 完整示例(2分钟)
136
+
137
+ ```javascript
138
+ const { dsl, Validator } = require('schema-dsl');
139
+
140
+ // 定义用户注册Schema
141
+ const registerSchema = dsl({
142
+ // 用户名:正则验证
143
+ username: 'string:3-32!'
144
+ .pattern(/^[a-zA-Z0-9_]+$/)
145
+ .label('用户名')
146
+ .messages({
147
+ 'pattern': '只能包含字母、数字和下划线',
148
+ 'min': '至少3个字符',
149
+ 'max': '最多32个字符'
150
+ }),
151
+
152
+ // 邮箱:标签
153
+ email: 'email!'.label('邮箱地址'),
154
+
155
+ // 密码:复杂正则
156
+ password: 'string:8-64!'
157
+ .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/)
158
+ .label('密码')
159
+ .messages({
160
+ 'pattern': '必须包含大小写字母和数字'
161
+ }),
162
+
163
+ // 简单字段
164
+ age: 'number:18-120',
165
+ gender: 'male|female|other'
166
+ });
167
+
168
+ // 验证数据
169
+ const testData = {
170
+ username: 'john_doe',
171
+ email: 'john@example.com',
172
+ password: 'Password123',
173
+ age: 25,
174
+ gender: 'male'
175
+ };
176
+
177
+ const result = validate(registerSchema, testData);
178
+
179
+ if (result.valid) {
180
+ console.log('✅ 验证通过!');
181
+ } else {
182
+ console.log('❌ 验证失败:', result.errors);
183
+ }
184
+ ```
185
+
186
+ ---
187
+
188
+ ## 💡 最佳实践
189
+
190
+ ### 1. 简单字段用纯DSL
191
+
192
+ ```javascript
193
+ const schema = dsl({
194
+ name: 'string:1-50!', // ✅ 简洁
195
+ age: 'number:18-120', // ✅ 清晰
196
+ role: 'user|admin' // ✅ 直观
197
+ });
198
+ ```
199
+
200
+ ### 2. 复杂字段用String扩展
201
+
202
+ ```javascript
203
+ const schema = dsl({
204
+ email: 'email!'
205
+ .pattern(/custom/)
206
+ .messages({...})
207
+ .label('邮箱'),
208
+
209
+ username: 'string:3-32!'
210
+ .pattern(/^\w+$/)
211
+ .custom(checkExists)
212
+ });
213
+ ```
214
+
215
+ ### 3. 80/20 法则
216
+
217
+ **80%字段用纯DSL,20%字段用String扩展**
218
+
219
+ ---
220
+
221
+ ## 🎯 常见场景
222
+
223
+ ### 表单验证
224
+
225
+ ```javascript
226
+ const formSchema = dsl({
227
+ email: 'email!'.label('邮箱地址'),
228
+ password: 'string:8-64!'.label('密码'),
229
+ nickname: 'string:2-20'.label('昵称'),
230
+ bio: 'string:500',
231
+ website: 'url',
232
+ age: 'number:18-120',
233
+ gender: 'male|female|other'
234
+ });
235
+ ```
236
+
237
+ ### 自定义验证
238
+
239
+ ```javascript
240
+ const schema = dsl({
241
+ username: 'string:3-32!'
242
+ .custom(async (value) => {
243
+ const exists = await checkUsernameExists(value);
244
+ if (exists) {
245
+ return '用户名已存在';
246
+ }
247
+ })
248
+ });
249
+ ```
250
+
251
+ ### 嵌套对象
252
+
253
+ ```javascript
254
+ const schema = dsl({
255
+ user: {
256
+ profile: {
257
+ name: 'string:1-50!'.label('姓名'),
258
+ avatar: 'url'.label('头像'),
259
+ social: {
260
+ twitter: 'url'.pattern(/twitter\.com/),
261
+ github: 'url'.pattern(/github\.com/)
262
+ }
263
+ }
264
+ }
265
+ });
266
+ ```
267
+
268
+ ---
269
+
270
+ ## 📚 下一步
271
+
272
+ ### 深入学习
273
+
274
+ - [DSL 语法完整指南](./dsl-syntax.md)
275
+ - [API 参考文档](./api-reference.md)
276
+ - [String 扩展文档](./string-extensions.md)
277
+
278
+ ### 示例代码
279
+
280
+ - [String扩展完整示例](../examples/string-extensions.js)
281
+ - [用户注册示例](../examples/user-registration/)
282
+ - [数据库导出示例](../examples/export-demo.js)
283
+
284
+ ### 高级功能
285
+
286
+ - [自定义验证器](./api-reference.md#custom)
287
+ - [条件验证(when)](./api-reference.md#when)
288
+ - [数据库Schema导出](./api-reference.md#导出器)
289
+
290
+ ---
291
+
292
+ ## 🎯 设计理念与性能
293
+
294
+ ### 为什么选择运行时解析?
295
+
296
+ Schema-DSL 使用**运行时解析 DSL**,而非编译时构建(如 Zod),这是有意的设计选择:
297
+
298
+ #### ✅ 运行时解析的优势
299
+
300
+ 1. **完全动态** - 验证规则可以从配置文件、数据库动态加载
301
+ ```javascript
302
+ // 从配置读取规则
303
+ const rules = await db.findOne({ entity: 'user' });
304
+ const schema = dsl({
305
+ username: `string:${rules.min}-${rules.max}!`
306
+ });
307
+ ```
308
+
309
+ 2. **多租户支持** - 每个租户可以有不同的验证规则
310
+ ```javascript
311
+ // 租户A: 用户名3-32字符
312
+ // 租户B: 用户名5-50字符
313
+ function getTenantSchema(tenantId) {
314
+ const rules = tenantConfig[tenantId];
315
+ return dsl({
316
+ username: `string:${rules.min}-${rules.max}!`
317
+ });
318
+ }
319
+ ```
320
+
321
+ 3. **可序列化** - DSL 字符串可以存储、传输、共享
322
+ ```javascript
323
+ // 存储到数据库
324
+ await db.insert({
325
+ formId: 'register',
326
+ rules: { username: 'string:3-32!', email: 'email!' }
327
+ });
328
+
329
+ // 通过 API 传输
330
+ res.json({ validationRules: rules });
331
+
332
+ // 前后端共享规则
333
+ ```
334
+
335
+ 4. **低代码基础** - 支持可视化表单构建器
336
+ ```javascript
337
+ // 管理员在界面配置验证规则
338
+ const formBuilder = {
339
+ fields: [
340
+ { name: 'username', validation: 'string:3-32!' }
341
+ ]
342
+ };
343
+ ```
344
+
345
+ #### ⚠️ 性能权衡
346
+
347
+ 运行时解析的代价是性能略低于编译时构建:
348
+
349
+ | 库名 | 每秒操作数 | 说明 |
350
+ |------|-----------|------|
351
+ | Ajv | 2,000,000 ops/s | 原生 JSON Schema(最快) |
352
+ | Zod | 526,316 ops/s | 编译时构建 |
353
+ | **Schema-DSL** | **277,778 ops/s** | 运行时解析(第3名) |
354
+ | Joi | 97,087 ops/s | 功能丰富 |
355
+ | Yup | 60,241 ops/s | React 生态 |
356
+
357
+ **结论**:
358
+ - ✅ Schema-DSL 比 Joi 快 **2.86倍**,比 Yup 快 **4.61倍**
359
+ - ✅ 对大多数应用足够(27万+ ops/s)
360
+ - ⚠️ 如需极致性能(>50万 ops/s),推荐使用 Zod 或 Ajv
361
+
362
+ **权衡**:
363
+ ```
364
+ 损失: 比 Zod 慢 1.9倍
365
+ 换来:
366
+ ✅ 代码量减少 65%
367
+ ✅ 完全动态的验证规则
368
+ ✅ 多租户/配置驱动支持
369
+ ✅ 前后端共享规则
370
+ ✅ 低代码平台基础
371
+ ```
372
+
373
+ ### 适用场景
374
+
375
+ **✅ 选择 Schema-DSL**:
376
+ - 需要动态验证规则(配置驱动、多租户)
377
+ - 需要数据库 Schema 导出
378
+ - 快速开发原型
379
+ - 多语言 SaaS 系统
380
+
381
+ **⚠️ 考虑其他库**:
382
+ - TypeScript 项目需要强类型推断 → **Zod**
383
+ - 性能是第一优先级 → **Ajv** 或 **Zod**
384
+ - 静态验证规则 → **Zod**
385
+
386
+ ---
387
+
388
+ ## 🆘 常见问题
389
+
390
+ ### Q: String扩展和纯DSL有什么区别?
391
+
392
+ **A**:
393
+ - **纯DSL**: 适合简单字段,语法简洁
394
+ - **String扩展**: 适合复杂验证,支持链式调用
395
+
396
+ ```javascript
397
+ // 纯DSL(简单)
398
+ name: 'string:1-50!'
399
+
400
+ // String扩展(复杂)
401
+ email: 'email!'
402
+ .pattern(/custom/)
403
+ .messages({...})
404
+ ```
405
+
406
+ ### Q: 如何禁用String扩展?
407
+
408
+ **A**:
409
+ ```javascript
410
+ const { uninstallStringExtensions } = require('schema-dsl');
411
+ uninstallStringExtensions();
412
+ ```
413
+
414
+ ### Q: 支持TypeScript吗?
415
+
416
+ **A**: 支持!SchemaIO提供完整的TypeScript类型定义。
417
+
418
+ ---
419
+
420
+ ## 🎉 恭喜!
421
+
422
+ 你已经掌握了SchemaIO的核心用法!
423
+
424
+ **核心要点**:
425
+ 1. ✅ DSL语法简洁直观
426
+ 2. ✅ String扩展强大灵活
427
+ 3. ✅ 80%用DSL,20%用扩展
428
+ 4. ✅ 字符串可以直接链式调用
429
+
430
+ **开始使用**: `npm install schema-dsl`
431
+
432
+ ---
433
+
434
+ ---
435
+
436
+ **最后更新**: 2025-12-26
437
+ - [🔧 自定义验证](#-自定义验证)
438
+ - [🗄️ 数据库导出](#️-数据库导出)
439
+ - [📚 下一步](#-下一步)
440
+
441
+ ---
442
+
443
+ ## 🚀 安装
444
+
445
+ ```bash
446
+ npm install schema-dsl
447
+ ```
448
+
449
+ ---
450
+
451
+ ## 📖 5分钟快速入门
452
+
453
+ ### 1. Hello World(30秒)
454
+
455
+ ```javascript
456
+ const { dsl, Validator } = require('schema-dsl');
457
+
458
+ // 定义Schema
459
+ const schema = dsl({
460
+ name: 'string:1-50!',
461
+ email: 'email!'
462
+ });
463
+
464
+ // 验证数据
465
+ const validator = new Validator();
466
+ const result = validator.validate(schema, {
467
+ name: '张三',
468
+ email: 'zhangsan@example.com'
469
+ });
470
+
471
+ console.log(result.valid); // true
472
+ ```
473
+
474
+ **解释**:
475
+ - `'string:1-50!'` - 必填字符串,长度1-50
476
+ - `'email!'` - 必填邮箱
477
+ - `!` 表示必填
478
+
479
+ ---
480
+
481
+ ### 2. DSL 语法速查(1分钟)
482
+
483
+ ```javascript
484
+ // 基本类型
485
+ 'string' // 字符串
486
+ 'number' // 数字
487
+ 'integer' // 整数
488
+ 'boolean' // 布尔值
489
+ 'email' // 邮箱
490
+ 'url' // URL
491
+ 'date' // 日期
492
+
493
+ // 约束
494
+ 'string:3-32' // 长度3-32(范围)
495
+ 'string:100' // 最大长度100(简写)
496
+ 'string:-100' // 最大长度100(明确写法)
497
+ 'string:10-' // 最小长度10(无最大限制)
498
+ 'number:18-120' // 范围18-120
499
+
500
+ // 必填
501
+ 'string!' // 必填字符串
502
+ 'email!' // 必填邮箱
503
+
504
+ // 枚举
505
+ 'active|inactive|pending' // 三选一
506
+
507
+ // 数组
508
+ 'array<string>' // 字符串数组
509
+ 'array:1-10<string>' // 1-10个字符串
510
+ 'array<string:1-50>' // 带约束的数组元素
511
+ ```
512
+
513
+ **语法规则**:
514
+ - `type:max` → 最大值(简写)
515
+ - `type:min-max` → 范围
516
+ - `type:min-` → 只限最小
517
+ - `type:-max` → 只限最大
518
+
519
+ ---
520
+
521
+ ### 3. String 扩展 - 核心特性(2分钟)
522
+
523
+ 字符串支持链式调用:
524
+
525
+ ```javascript
526
+ const schema = dsl({
527
+ // ✨ 字符串直接链式调用,无需 dsl() 包裹
528
+ email: 'email!'
529
+ .pattern(/custom/)
530
+ .label('邮箱地址'),
531
+
532
+ username: 'string:3-32!'
533
+ .pattern(/^[a-zA-Z0-9_]+$/)
534
+ .messages({
535
+ 'string.pattern': '只能包含字母、数字和下划线'
536
+ })
537
+ .label('用户名'),
538
+
539
+ // 简单字段仍然可以用纯DSL
540
+ age: 'number:18-120',
541
+ role: 'user|admin'
542
+ });
543
+ ```
544
+
545
+ **可用方法**:
546
+ - `.pattern(regex)` - 正则验证
547
+ - `.label(text)` - 字段标签
548
+ - `.messages(obj)` - 自定义消息
549
+ - `.description(text)` - 描述
550
+ - `.custom(fn)` - 自定义验证器
551
+
552
+ ---
553
+
554
+ ### 4. 完整示例(2分钟)
555
+
556
+ ```javascript
557
+ const { dsl, validate } = require('schema-dsl');
558
+
559
+ // 定义用户注册Schema
560
+ const registerSchema = dsl({
561
+ // 用户名:正则验证
562
+ username: 'string:3-32!'
563
+ .pattern(/^[a-zA-Z0-9_]+$/)
564
+ .label('用户名')
565
+ .messages({
566
+ 'pattern': '只能包含字母、数字和下划线',
567
+ 'min': '至少3个字符',
568
+ 'max': '最多32个字符'
569
+ }),
570
+
571
+ // 邮箱:标签
572
+ email: 'email!'.label('邮箱地址'),
573
+
574
+ // 密码:复杂正则
575
+ password: 'string:8-64!'
576
+ .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/)
577
+ .label('密码')
578
+ .messages({
579
+ 'pattern': '必须包含大小写字母和数字'
580
+ }),
581
+
582
+ // 简单字段
583
+ age: 'number:18-120',
584
+ gender: 'male|female|other'
585
+ });
586
+
587
+ // 验证数据
588
+ const testData = {
589
+ username: 'john_doe',
590
+ email: 'john@example.com',
591
+ password: 'Password123',
592
+ age: 25,
593
+ gender: 'male'
594
+ };
595
+
596
+ const result = validate(registerSchema, testData);
597
+
598
+ if (result.valid) {
599
+ console.log('✅ 验证通过!');
600
+ } else {
601
+ console.log('❌ 验证失败:', result.errors);
602
+ }
603
+ ```
604
+
605
+ ---
606
+
607
+ ## 💡 最佳实践
608
+
609
+ ### 1. 简单字段用纯DSL
610
+
611
+ ```javascript
612
+ const schema = dsl({
613
+ name: 'string:1-50!', // ✅ 简洁
614
+ age: 'number:18-120', // ✅ 清晰
615
+ role: 'user|admin' // ✅ 直观
616
+ });
617
+ ```
618
+
619
+ ### 2. 复杂字段用String扩展
620
+
621
+ ```javascript
622
+ const schema = dsl({
623
+ email: 'email!'
624
+ .pattern(/custom/)
625
+ .messages({...})
626
+ .label('邮箱'),
627
+
628
+ username: 'string:3-32!'
629
+ .pattern(/^\w+$/)
630
+ .custom(checkExists)
631
+ });
632
+ ```
633
+
634
+ ### 3. 80/20 法则
635
+
636
+ **80%字段用纯DSL,20%字段用String扩展**
637
+
638
+ ---
639
+
640
+ ## 🎯 常见场景
641
+
642
+ ### 表单验证
643
+
644
+ ```javascript
645
+ const formSchema = dsl({
646
+ email: 'email!'.label('邮箱地址'),
647
+ password: 'string:8-64!'.label('密码'),
648
+ nickname: 'string:2-20'.label('昵称'),
649
+ bio: 'string:500',
650
+ website: 'url',
651
+ age: 'number:18-120',
652
+ gender: 'male|female|other'
653
+ });
654
+ ```
655
+
656
+ ### 自定义验证
657
+
658
+ ```javascript
659
+ const schema = dsl({
660
+ username: 'string:3-32!'
661
+ .custom(async (value) => {
662
+ const exists = await checkUsernameExists(value);
663
+ if (exists) {
664
+ return { error: 'username.exists', message: '用户名已存在' };
665
+ }
666
+ return true;
667
+ })
668
+ });
669
+ ```
670
+
671
+ ### 嵌套对象
672
+
673
+ ```javascript
674
+ const schema = dsl({
675
+ user: {
676
+ profile: {
677
+ name: 'string:1-50!'.label('姓名'),
678
+ avatar: 'url'.label('头像'),
679
+ social: {
680
+ twitter: 'url'.pattern(/twitter\.com/),
681
+ github: 'url'.pattern(/github\.com/)
682
+ }
683
+ }
684
+ }
685
+ });
686
+ ```
687
+
688
+ ---
689
+
690
+ ## 📚 下一步
691
+
692
+ ### 深入学习
693
+
694
+ - [DSL 语法完整指南](./dsl-syntax.md)
695
+ - [API 参考文档](./api-reference.md)
696
+ - [String 扩展文档](./string-extensions.md)
697
+
698
+ ### 示例代码
699
+
700
+ - [String扩展完整示例](../examples/string-extensions.js)
701
+ - [用户注册示例](../examples/user-registration/)
702
+ - [数据库导出示例](../examples/export-demo.js)
703
+
704
+ ### 高级功能
705
+
706
+ - [自定义验证器](./api-reference.md#custom)
707
+ - [条件验证(when)](./api-reference.md#when)
708
+ - [数据库Schema导出](./api-reference.md#导出器)
709
+
710
+ ---
711
+
712
+ ## 🆘 常见问题
713
+
714
+ ### Q: String扩展和纯DSL有什么区别?
715
+
716
+ **A**:
717
+ - **纯DSL**: 适合简单字段,语法简洁
718
+ - **String扩展**: 适合复杂验证,支持链式调用
719
+
720
+ ```javascript
721
+ // 纯DSL(简单)
722
+ name: 'string:1-50!'
723
+
724
+ // String扩展(复杂)
725
+ email: 'email!'
726
+ .pattern(/custom/)
727
+ .messages({...})
728
+ ```
729
+
730
+ ### Q: 如何禁用String扩展?
731
+
732
+ **A**:
733
+ ```javascript
734
+ const { uninstallStringExtensions } = require('schema-dsl');
735
+ uninstallStringExtensions();
736
+ ```
737
+
738
+ ### Q: 支持TypeScript吗?
739
+
740
+ **A**: 支持!SchemaIO提供完整的TypeScript类型定义。
741
+
742
+ ---
743
+
744
+ ## 🎉 恭喜!
745
+
746
+ 你已经掌握了SchemaIO的核心用法!
747
+
748
+ **核心要点**:
749
+ 1. ✅ DSL语法简洁直观
750
+ 2. ✅ String扩展强大灵活
751
+ 3. ✅ 80%用DSL,20%用扩展
752
+ 4. ✅ 字符串可以直接链式调用
753
+
754
+ **开始使用**: `npm install schema-dsl`
755
+
756
+ ---
757
+
758
+
759
+ **最后更新**: 2025-12-25
760
+
761
+