schema-dsl 2.0.0 → 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 (145) hide show
  1. package/CHANGELOG.md +130 -113
  2. package/LICENSE +21 -21
  3. package/README.md +628 -628
  4. package/dist/{DslBuilder-DkLaOo9Q.d.ts → DslBuilder-BIgQOAXp.d.ts} +2 -0
  5. package/dist/{DslBuilder-DQDN0ZxZ.d.cts → DslBuilder-CjHTucNQ.d.cts} +2 -0
  6. package/dist/{Validator-hFWKGxir.d.ts → Validator-CllRdrY0.d.ts} +1 -1
  7. package/dist/{Validator-C7GsVQOH.d.cts → Validator-D6okG9tr.d.cts} +1 -1
  8. package/dist/index.cjs +75 -29
  9. package/dist/index.d.cts +10 -4
  10. package/dist/index.d.ts +10 -4
  11. package/dist/index.js +75 -29
  12. package/dist/plugins/custom-format.cjs +33 -17
  13. package/dist/plugins/custom-format.d.cts +1 -1
  14. package/dist/plugins/custom-format.d.ts +1 -1
  15. package/dist/plugins/custom-format.js +33 -17
  16. package/dist/plugins/custom-type-example.cjs +33 -17
  17. package/dist/plugins/custom-type-example.d.cts +1 -1
  18. package/dist/plugins/custom-type-example.d.ts +1 -1
  19. package/dist/plugins/custom-type-example.js +33 -17
  20. package/dist/plugins/custom-validator.cjs +0 -2
  21. package/dist/plugins/custom-validator.d.cts +1 -1
  22. package/dist/plugins/custom-validator.d.ts +1 -1
  23. package/dist/plugins/custom-validator.js +0 -2
  24. package/docs/FEATURE-INDEX.md +553 -553
  25. package/docs/add-custom-locale.md +496 -496
  26. package/docs/add-keyword.md +24 -24
  27. package/docs/api-reference.md +1047 -1047
  28. package/docs/api.md +13 -13
  29. package/docs/best-practices-project-structure.md +417 -417
  30. package/docs/best-practices.md +712 -712
  31. package/docs/cache-manager.md +344 -344
  32. package/docs/compile.md +45 -45
  33. package/docs/conditional-api.md +1307 -1307
  34. package/docs/custom-extensions-guide.md +339 -339
  35. package/docs/design-philosophy.md +606 -606
  36. package/docs/doc-index.md +324 -324
  37. package/docs/dsl-syntax.md +714 -714
  38. package/docs/dynamic-locale.md +608 -608
  39. package/docs/enum.md +482 -482
  40. package/docs/error-handling.md +1975 -1975
  41. package/docs/export-guide.md +501 -501
  42. package/docs/export-limitations.md +567 -567
  43. package/docs/faq.md +596 -596
  44. package/docs/frontend-i18n-guide.md +307 -307
  45. package/docs/i18n-user-guide.md +487 -487
  46. package/docs/i18n.md +476 -476
  47. package/docs/index.md +48 -48
  48. package/docs/json-schema-basics.md +40 -40
  49. package/docs/label-vs-description.md +271 -271
  50. package/docs/markdown-exporter.md +406 -406
  51. package/docs/mongodb-exporter.md +302 -302
  52. package/docs/multi-language.md +26 -26
  53. package/docs/multi-type-support.md +322 -322
  54. package/docs/mysql-exporter.md +280 -280
  55. package/docs/number-operators.md +449 -449
  56. package/docs/optional-marker-guide.md +326 -326
  57. package/docs/performance-guide.md +49 -49
  58. package/docs/plugin-system.md +381 -381
  59. package/docs/plugin-type-registration.md +34 -34
  60. package/docs/postgresql-exporter.md +311 -311
  61. package/docs/public/favicon.svg +4 -4
  62. package/docs/quick-start.md +435 -435
  63. package/docs/runtime-locale-support.md +532 -532
  64. package/docs/schema-helper.md +345 -345
  65. package/docs/schema-utils-advanced-issues.md +23 -23
  66. package/docs/schema-utils-best-practices.md +20 -20
  67. package/docs/schema-utils-chaining.md +150 -150
  68. package/docs/schema-utils.md +524 -524
  69. package/docs/security-checklist.md +20 -20
  70. package/docs/string-extensions.md +488 -488
  71. package/docs/troubleshooting.md +486 -486
  72. package/docs/type-converter.md +310 -310
  73. package/docs/type-reference.md +242 -242
  74. package/docs/typescript-guide.md +584 -584
  75. package/docs/union-type-guide.md +157 -157
  76. package/docs/union-types.md +284 -284
  77. package/docs/validate-async.md +491 -491
  78. package/docs/validate-batch.md +49 -49
  79. package/docs/validate-dsl-object-support.md +578 -578
  80. package/docs/validate.md +506 -506
  81. package/docs/validation-guide.md +502 -502
  82. package/docs/validator.md +39 -39
  83. package/package.json +131 -131
  84. package/plugins/custom-format.cjs +8 -8
  85. package/plugins/custom-type-example.cjs +8 -8
  86. package/plugins/custom-validator.cjs +8 -8
  87. package/src/adapters/DslAdapter.ts +111 -111
  88. package/src/adapters/index.ts +1 -1
  89. package/src/config/constants.ts +83 -83
  90. package/src/config/index.ts +2 -2
  91. package/src/config/patterns.ts +77 -77
  92. package/src/core/CacheManager.ts +169 -159
  93. package/src/core/ConditionalBuilder.ts +382 -382
  94. package/src/core/ConditionalRuntime.ts +27 -27
  95. package/src/core/ConditionalValidator.ts +254 -254
  96. package/src/core/DslBuilder.ts +687 -677
  97. package/src/core/ErrorCodes.ts +38 -38
  98. package/src/core/ErrorFormatter.ts +271 -271
  99. package/src/core/JSONSchemaCore.ts +65 -65
  100. package/src/core/Locale.ts +187 -187
  101. package/src/core/MessageTemplate.ts +42 -42
  102. package/src/core/ObjectDslBuilder.ts +64 -64
  103. package/src/core/PluginManager.ts +326 -326
  104. package/src/core/StringExtensions.ts +140 -140
  105. package/src/core/TemplateEngine.ts +44 -44
  106. package/src/core/Validator.ts +448 -448
  107. package/src/errors/I18nError.ts +159 -159
  108. package/src/errors/ValidationError.ts +105 -105
  109. package/src/exporters/BaseExporter.ts +60 -60
  110. package/src/exporters/MarkdownExporter.ts +305 -305
  111. package/src/exporters/MongoDBExporter.ts +126 -126
  112. package/src/exporters/MySQLExporter.ts +156 -155
  113. package/src/exporters/PostgreSQLExporter.ts +222 -222
  114. package/src/exporters/index.ts +18 -18
  115. package/src/index.ts +651 -633
  116. package/src/locales/en-US.ts +160 -160
  117. package/src/locales/es-ES.ts +160 -160
  118. package/src/locales/fr-FR.ts +160 -160
  119. package/src/locales/index.ts +103 -103
  120. package/src/locales/ja-JP.ts +160 -160
  121. package/src/locales/types.ts +156 -156
  122. package/src/locales/zh-CN.ts +160 -160
  123. package/src/parser/ConstraintParser.ts +101 -101
  124. package/src/parser/DslParser.ts +470 -470
  125. package/src/parser/SchemaCompiler.ts +66 -66
  126. package/src/parser/TypeRegistry.ts +250 -250
  127. package/src/parser/index.ts +6 -6
  128. package/src/plugins/custom-format.ts +124 -126
  129. package/src/plugins/custom-type-example.ts +106 -108
  130. package/src/plugins/custom-validator.ts +138 -140
  131. package/src/types/conditional.ts +28 -28
  132. package/src/types/config.ts +59 -59
  133. package/src/types/dsl.ts +131 -131
  134. package/src/types/error.ts +60 -60
  135. package/src/types/index.ts +17 -17
  136. package/src/types/infer.ts +127 -127
  137. package/src/types/plugin.ts +58 -58
  138. package/src/types/safe-regex.d.ts +9 -9
  139. package/src/types/schema.ts +66 -66
  140. package/src/types/validate.ts +71 -71
  141. package/src/utils/SchemaHelper.ts +196 -196
  142. package/src/utils/SchemaUtils.ts +365 -346
  143. package/src/utils/TypeConverter.ts +215 -215
  144. package/src/utils/index.ts +10 -10
  145. package/src/validators/CustomKeywords.ts +477 -477
@@ -1,435 +1,435 @@
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
- > **Node.js 要求**:`>=18.0.0`
32
- >
33
- > 当前 TypeScript 重构版以 `Node.js >=18.0.0` 为唯一运行时基线,不再承诺旧 Node 版本兼容。
34
-
35
- ---
36
-
37
- ## 📖 5分钟快速入门
38
-
39
- ### 1. Hello World(30秒)
40
-
41
- ```javascript
42
- const { dsl, validate } = require('schema-dsl');
43
-
44
- // 定义Schema
45
- const schema = dsl({
46
- name: 'string:1-50!',
47
- email: 'email!'
48
- });
49
-
50
- // 验证数据(使用便捷函数)
51
- const result = validate(schema, {
52
- name: '张三',
53
- email: 'zhangsan@example.com'
54
- });
55
-
56
- console.log(result.valid); // true
57
- ```
58
-
59
- **解释**:
60
- - `'string:1-50!'` - 必填字符串,长度1-50
61
- - `'email!'` - 必填邮箱
62
- - `!` 表示必填
63
-
64
- ---
65
-
66
- ### 2. DSL 语法速查(1分钟)
67
-
68
- ```javascript
69
- // 基本类型
70
- 'string' // 字符串
71
- 'number' // 数字
72
- 'integer' // 整数
73
- 'boolean' // 布尔值
74
- 'email' // 邮箱
75
- 'url' // URL
76
- 'date' // 日期
77
-
78
- // 约束
79
- 'string:3-32' // 长度3-32(范围)
80
- 'string:100' // 最大长度100(简写)
81
- 'string:-100' // 最大长度100(明确写法)
82
- 'string:10-' // 最小长度10(无最大限制)
83
- 'number:18-120' // 范围18-120
84
-
85
- // 必填
86
- 'string!' // 必填字符串
87
- 'email!' // 必填邮箱
88
-
89
- // 枚举
90
- 'active|inactive|pending' // 三选一
91
-
92
- // 数组
93
- 'array<string>' // 字符串数组
94
- 'array:1-10<string>' // 1-10个字符串
95
- 'array<string:1-50>' // 带约束的数组元素
96
- ```
97
-
98
- **语法规则**:
99
- - `type:max` → 最大值(简写)
100
- - `type:min-max` → 范围
101
- - `type:min-` → 只限最小
102
- - `type:-max` → 只限最大
103
-
104
- ---
105
-
106
- ### 3. String 扩展(2分钟)
107
-
108
- 字符串支持链式调用:
109
-
110
- ```javascript
111
- const schema = dsl({
112
- // 字符串直接链式调用,无需 dsl() 包裹
113
- email: 'email!'
114
- .pattern(/custom/)
115
- .label('邮箱地址'),
116
-
117
- username: 'string:3-32!'
118
- .pattern(/^[a-zA-Z0-9_]+$/)
119
- .messages({
120
- 'pattern': '只能包含字母、数字和下划线'
121
- })
122
- .label('用户名'),
123
-
124
- // 简单字段仍然可以用纯DSL
125
- age: 'number:18-120',
126
- role: 'user|admin'
127
- });
128
- ```
129
-
130
- **可用方法**:
131
- - `.pattern(regex)` - 正则验证
132
- - `.label(text)` - 字段标签
133
- - `.messages(obj)` - 自定义消息
134
- - `.description(text)` - 描述
135
- - `.custom(fn)` - 自定义验证器
136
-
137
- ---
138
-
139
- ### 4. 完整示例(2分钟)
140
-
141
- ```javascript
142
- const { dsl, validate } = require('schema-dsl');
143
-
144
- // 定义用户注册Schema
145
- const registerSchema = dsl({
146
- // 用户名:正则验证
147
- username: dsl('string:3-32!')
148
- .pattern(/^[a-zA-Z0-9_]+$/)
149
- .label('用户名')
150
- .error({
151
- pattern: '只能包含字母、数字和下划线'
152
- }),
153
-
154
- // 邮箱:标签
155
- email: dsl('email!').label('邮箱地址'),
156
-
157
- // 密码:复杂正则
158
- password: dsl('string:8-64!')
159
- .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/)
160
- .label('密码')
161
- .error({
162
- pattern: '必须包含大小写字母和数字'
163
- }),
164
-
165
- // 简单字段
166
- age: 'number:18-120',
167
- role: 'user|admin'
168
- });
169
-
170
- // 验证数据
171
- const testData = {
172
- username: 'john_doe',
173
- email: 'john@example.com',
174
- password: 'Password123',
175
- age: 25,
176
- role: 'user'
177
- };
178
-
179
- const result = validate(registerSchema, testData);
180
-
181
- if (result.valid) {
182
- console.log('✅ 验证通过!');
183
- } else {
184
- console.log('❌ 验证失败:', result.errors);
185
- }
186
- ```
187
-
188
- ---
189
-
190
- ## 💡 最佳实践
191
-
192
- ### 1. 简单字段用纯DSL
193
-
194
- ```javascript
195
- const schema = dsl({
196
- name: 'string:1-50!', // ✅ 简洁
197
- age: 'number:18-120', // ✅ 清晰
198
- role: 'user|admin' // ✅ 直观
199
- });
200
- ```
201
-
202
- ### 2. 复杂字段用String扩展
203
-
204
- ```javascript
205
- const schema = dsl({
206
- email: 'email!'
207
- .pattern(/custom/)
208
- .messages({...})
209
- .label('邮箱'),
210
-
211
- username: 'string:3-32!'
212
- .pattern(/^\w+$/)
213
- .custom(checkExists)
214
- });
215
- ```
216
-
217
- ### 3. 80/20 法则
218
-
219
- **80%字段用纯DSL,20%字段用String扩展**
220
-
221
- ---
222
-
223
- ## 🎯 常见场景
224
-
225
- ### 表单验证
226
-
227
- ```javascript
228
- const formSchema = dsl({
229
- email: 'email!'.label('邮箱地址'),
230
- password: 'string:8-64!'.label('密码'),
231
- nickname: 'string:2-20'.label('昵称'),
232
- bio: 'string:500',
233
- website: 'url',
234
- age: 'number:18-120',
235
- gender: 'male|female|other'
236
- });
237
- ```
238
-
239
- ### 自定义验证
240
-
241
- > `.custom()` 当前仅支持同步函数;如果需要异步查重,请在 `validate()` / `validateAsync()` 通过后于业务层单独执行。
242
-
243
- ```javascript
244
- const schema = dsl({
245
- username: 'string:3-32!'
246
- .custom((value) => {
247
- if (value === 'admin') {
248
- return '用户名已存在';
249
- }
250
- })
251
- });
252
- ```
253
-
254
- ### 嵌套对象
255
-
256
- ```javascript
257
- const schema = dsl({
258
- user: {
259
- profile: {
260
- name: 'string:1-50!'.label('姓名'),
261
- avatar: 'url'.label('头像'),
262
- social: {
263
- twitter: 'url'.pattern(/twitter\.com/),
264
- github: 'url'.pattern(/github\.com/)
265
- }
266
- }
267
- }
268
- });
269
- ```
270
-
271
- ---
272
-
273
- ## 📚 下一步
274
-
275
- ### 深入学习
276
-
277
- - [DSL 语法完整指南](./dsl-syntax.md)
278
- - [API 参考文档](./api-reference.md)
279
- - [String 扩展文档](./string-extensions.md)
280
-
281
- ### 示例代码
282
-
283
- - [Quick Start 完整示例](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/quick-start.ts)
284
-
285
- 其余主题示例现在都已分别挂到各自文档底部,并统一切到稳定 GitHub 示例链接。
286
-
287
- ### 高级功能
288
-
289
- - [自定义验证器](./api-reference.md#custom)
290
- - [条件验证(when)](./api-reference.md#when)
291
- - [数据库Schema导出](./api-reference.md#导出器)
292
-
293
- ---
294
-
295
- ## 🎯 设计理念与性能
296
-
297
- ### 为什么选择运行时解析?
298
-
299
- Schema-DSL 使用**运行时解析 DSL**,而非编译时构建(如 Zod),这是有意的设计选择:
300
-
301
- #### ✅ 运行时解析的优势
302
-
303
- 1. **完全动态** - 验证规则可以从配置文件、数据库动态加载
304
- ```javascript
305
- // 从配置读取规则
306
- const rules = await db.findOne({ entity: 'user' });
307
- const schema = dsl({
308
- username: `string:${rules.min}-${rules.max}!`
309
- });
310
- ```
311
-
312
- 2. **多租户支持** - 每个租户可以有不同的验证规则
313
- ```javascript
314
- // 租户A: 用户名3-32字符
315
- // 租户B: 用户名5-50字符
316
- function getTenantSchema(tenantId) {
317
- const rules = tenantConfig[tenantId];
318
- return dsl({
319
- username: `string:${rules.min}-${rules.max}!`
320
- });
321
- }
322
- ```
323
-
324
- 3. **可序列化** - DSL 字符串可以存储、传输、共享
325
- ```javascript
326
- // 存储到数据库
327
- await db.insert({
328
- formId: 'register',
329
- rules: { username: 'string:3-32!', email: 'email!' }
330
- });
331
-
332
- // 通过 API 传输
333
- res.json({ validationRules: rules });
334
-
335
- // 前后端共享规则
336
- ```
337
-
338
- 4. **低代码基础** - 支持可视化表单构建器
339
- ```javascript
340
- // 管理员在界面配置验证规则
341
- const formBuilder = {
342
- fields: [
343
- { name: 'username', validation: 'string:3-32!' }
344
- ]
345
- };
346
- ```
347
-
348
- #### ⚠️ 性能权衡
349
-
350
- S1 有效数据与 Zod 持平,S3 嵌套场景快约 28%,无效数据公平对比快 89x:
351
-
352
- | 库名 | 性能 | 场景 |
353
- |------|-----------|------|
354
- | Ajv (raw) | 4.732M ops/s | 底层引擎,无 DSL 层 |
355
- | **Schema-DSL** | **1.301M ops/s**(S1有效) | 全功能(DSL + i18n + coerce)|
356
- | **Schema-DSL** | **1.205M ops/s**(S2 无效,均无 i18n)| 公平对比(均无 i18n)|
357
- | Zod | 1.305M ops/s(S1有效)/ 13.49K(S2 无效)| 编译时构建,错误路径异常驱动 |
358
- | Joi | 154K ops/s | 功能丰富 |
359
-
360
- **结论**:
361
- - ✅ S3 嵌套有效场景比 Zod 快 **28%**;S1 简单有效场景持平(差 <1%)
362
- - ✅ 无效数据公平对比(均无 i18n)比 Zod 快 **89x**
363
- - ✅ 内置缓存,热路径零解析开销
364
-
365
- ### 适用场景
366
-
367
- **✅ 选择 Schema-DSL**:
368
- - 需要动态验证规则(配置驱动、多租户)
369
- - 需要数据库 Schema 导出
370
- - 快速开发原型
371
- - 多语言 SaaS 系统
372
-
373
- **⚠️ 考虑其他库**:
374
- - TypeScript 项目需要强类型推断 → **Zod**
375
- - 性能是第一优先级 → **Ajv** 或 **Zod**
376
- - 静态验证规则 → **Zod**
377
-
378
- ---
379
-
380
- ## 🆘 常见问题
381
-
382
- ### Q: String扩展和纯DSL有什么区别?
383
-
384
- **A**:
385
- - **纯DSL**: 适合简单字段,语法简洁
386
- - **String扩展**: 适合复杂验证,支持链式调用
387
-
388
- ```javascript
389
- // 纯DSL(简单)
390
- name: 'string:1-50!'
391
-
392
- // String扩展(复杂)
393
- email: 'email!'
394
- .pattern(/custom/)
395
- .messages({...})
396
- ```
397
-
398
- ### Q: 如何禁用String扩展?
399
-
400
- **A**:
401
- ```javascript
402
- const { uninstallStringExtensions } = require('schema-dsl');
403
- uninstallStringExtensions();
404
- ```
405
-
406
- ### Q: 支持TypeScript吗?
407
-
408
- **A**: 支持!schema-dsl 提供完整的 TypeScript 类型定义。
409
-
410
- ---
411
-
412
- ## 🎉 恭喜!
413
-
414
- 你已经掌握了 schema-dsl 的核心用法!
415
-
416
- **核心要点**:
417
- 1. ✅ DSL语法简洁直观
418
- 2. ✅ String扩展强大灵活
419
- 3. ✅ 80%用DSL,20%用扩展
420
- 4. ✅ 字符串可以直接链式调用
421
-
422
- **开始使用**: `npm install schema-dsl`
423
-
424
- ---
425
-
426
- ## 对应示例文件
427
-
428
- **示例入口**: [quick-start.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/quick-start.ts)
429
- **说明**: 覆盖快速上手中的 Hello World、String 扩展、用户注册示例,以及 `validate()` 与 `Validator.compile()` 的基础复用路径,可直接运行参考。
430
-
431
- ---
432
-
433
- **最后更新**: 2026-05-08
434
-
435
-
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
+ > **Node.js 要求**:`>=18.0.0`
32
+ >
33
+ > 当前 TypeScript 重构版以 `Node.js >=18.0.0` 为唯一运行时基线,不再承诺旧 Node 版本兼容。
34
+
35
+ ---
36
+
37
+ ## 📖 5分钟快速入门
38
+
39
+ ### 1. Hello World(30秒)
40
+
41
+ ```javascript
42
+ const { dsl, validate } = require('schema-dsl');
43
+
44
+ // 定义Schema
45
+ const schema = dsl({
46
+ name: 'string:1-50!',
47
+ email: 'email!'
48
+ });
49
+
50
+ // 验证数据(使用便捷函数)
51
+ const result = validate(schema, {
52
+ name: '张三',
53
+ email: 'zhangsan@example.com'
54
+ });
55
+
56
+ console.log(result.valid); // true
57
+ ```
58
+
59
+ **解释**:
60
+ - `'string:1-50!'` - 必填字符串,长度1-50
61
+ - `'email!'` - 必填邮箱
62
+ - `!` 表示必填
63
+
64
+ ---
65
+
66
+ ### 2. DSL 语法速查(1分钟)
67
+
68
+ ```javascript
69
+ // 基本类型
70
+ 'string' // 字符串
71
+ 'number' // 数字
72
+ 'integer' // 整数
73
+ 'boolean' // 布尔值
74
+ 'email' // 邮箱
75
+ 'url' // URL
76
+ 'date' // 日期
77
+
78
+ // 约束
79
+ 'string:3-32' // 长度3-32(范围)
80
+ 'string:100' // 最大长度100(简写)
81
+ 'string:-100' // 最大长度100(明确写法)
82
+ 'string:10-' // 最小长度10(无最大限制)
83
+ 'number:18-120' // 范围18-120
84
+
85
+ // 必填
86
+ 'string!' // 必填字符串
87
+ 'email!' // 必填邮箱
88
+
89
+ // 枚举
90
+ 'active|inactive|pending' // 三选一
91
+
92
+ // 数组
93
+ 'array<string>' // 字符串数组
94
+ 'array:1-10<string>' // 1-10个字符串
95
+ 'array<string:1-50>' // 带约束的数组元素
96
+ ```
97
+
98
+ **语法规则**:
99
+ - `type:max` → 最大值(简写)
100
+ - `type:min-max` → 范围
101
+ - `type:min-` → 只限最小
102
+ - `type:-max` → 只限最大
103
+
104
+ ---
105
+
106
+ ### 3. String 扩展(2分钟)
107
+
108
+ 字符串支持链式调用:
109
+
110
+ ```javascript
111
+ const schema = dsl({
112
+ // 字符串直接链式调用,无需 dsl() 包裹
113
+ email: 'email!'
114
+ .pattern(/custom/)
115
+ .label('邮箱地址'),
116
+
117
+ username: 'string:3-32!'
118
+ .pattern(/^[a-zA-Z0-9_]+$/)
119
+ .messages({
120
+ 'pattern': '只能包含字母、数字和下划线'
121
+ })
122
+ .label('用户名'),
123
+
124
+ // 简单字段仍然可以用纯DSL
125
+ age: 'number:18-120',
126
+ role: 'user|admin'
127
+ });
128
+ ```
129
+
130
+ **可用方法**:
131
+ - `.pattern(regex)` - 正则验证
132
+ - `.label(text)` - 字段标签
133
+ - `.messages(obj)` - 自定义消息
134
+ - `.description(text)` - 描述
135
+ - `.custom(fn)` - 自定义验证器
136
+
137
+ ---
138
+
139
+ ### 4. 完整示例(2分钟)
140
+
141
+ ```javascript
142
+ const { dsl, validate } = require('schema-dsl');
143
+
144
+ // 定义用户注册Schema
145
+ const registerSchema = dsl({
146
+ // 用户名:正则验证
147
+ username: dsl('string:3-32!')
148
+ .pattern(/^[a-zA-Z0-9_]+$/)
149
+ .label('用户名')
150
+ .error({
151
+ pattern: '只能包含字母、数字和下划线'
152
+ }),
153
+
154
+ // 邮箱:标签
155
+ email: dsl('email!').label('邮箱地址'),
156
+
157
+ // 密码:复杂正则
158
+ password: dsl('string:8-64!')
159
+ .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$/)
160
+ .label('密码')
161
+ .error({
162
+ pattern: '必须包含大小写字母和数字'
163
+ }),
164
+
165
+ // 简单字段
166
+ age: 'number:18-120',
167
+ role: 'user|admin'
168
+ });
169
+
170
+ // 验证数据
171
+ const testData = {
172
+ username: 'john_doe',
173
+ email: 'john@example.com',
174
+ password: 'Password123',
175
+ age: 25,
176
+ role: 'user'
177
+ };
178
+
179
+ const result = validate(registerSchema, testData);
180
+
181
+ if (result.valid) {
182
+ console.log('✅ 验证通过!');
183
+ } else {
184
+ console.log('❌ 验证失败:', result.errors);
185
+ }
186
+ ```
187
+
188
+ ---
189
+
190
+ ## 💡 最佳实践
191
+
192
+ ### 1. 简单字段用纯DSL
193
+
194
+ ```javascript
195
+ const schema = dsl({
196
+ name: 'string:1-50!', // ✅ 简洁
197
+ age: 'number:18-120', // ✅ 清晰
198
+ role: 'user|admin' // ✅ 直观
199
+ });
200
+ ```
201
+
202
+ ### 2. 复杂字段用String扩展
203
+
204
+ ```javascript
205
+ const schema = dsl({
206
+ email: 'email!'
207
+ .pattern(/custom/)
208
+ .messages({...})
209
+ .label('邮箱'),
210
+
211
+ username: 'string:3-32!'
212
+ .pattern(/^\w+$/)
213
+ .custom(checkExists)
214
+ });
215
+ ```
216
+
217
+ ### 3. 80/20 法则
218
+
219
+ **80%字段用纯DSL,20%字段用String扩展**
220
+
221
+ ---
222
+
223
+ ## 🎯 常见场景
224
+
225
+ ### 表单验证
226
+
227
+ ```javascript
228
+ const formSchema = dsl({
229
+ email: 'email!'.label('邮箱地址'),
230
+ password: 'string:8-64!'.label('密码'),
231
+ nickname: 'string:2-20'.label('昵称'),
232
+ bio: 'string:500',
233
+ website: 'url',
234
+ age: 'number:18-120',
235
+ gender: 'male|female|other'
236
+ });
237
+ ```
238
+
239
+ ### 自定义验证
240
+
241
+ > `.custom()` 当前仅支持同步函数;如果需要异步查重,请在 `validate()` / `validateAsync()` 通过后于业务层单独执行。
242
+
243
+ ```javascript
244
+ const schema = dsl({
245
+ username: 'string:3-32!'
246
+ .custom((value) => {
247
+ if (value === 'admin') {
248
+ return '用户名已存在';
249
+ }
250
+ })
251
+ });
252
+ ```
253
+
254
+ ### 嵌套对象
255
+
256
+ ```javascript
257
+ const schema = dsl({
258
+ user: {
259
+ profile: {
260
+ name: 'string:1-50!'.label('姓名'),
261
+ avatar: 'url'.label('头像'),
262
+ social: {
263
+ twitter: 'url'.pattern(/twitter\.com/),
264
+ github: 'url'.pattern(/github\.com/)
265
+ }
266
+ }
267
+ }
268
+ });
269
+ ```
270
+
271
+ ---
272
+
273
+ ## 📚 下一步
274
+
275
+ ### 深入学习
276
+
277
+ - [DSL 语法完整指南](./dsl-syntax.md)
278
+ - [API 参考文档](./api-reference.md)
279
+ - [String 扩展文档](./string-extensions.md)
280
+
281
+ ### 示例代码
282
+
283
+ - [Quick Start 完整示例](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/quick-start.ts)
284
+
285
+ 其余主题示例现在都已分别挂到各自文档底部,并统一切到稳定 GitHub 示例链接。
286
+
287
+ ### 高级功能
288
+
289
+ - [自定义验证器](./api-reference.md#custom)
290
+ - [条件验证(when)](./api-reference.md#when)
291
+ - [数据库Schema导出](./api-reference.md#导出器)
292
+
293
+ ---
294
+
295
+ ## 🎯 设计理念与性能
296
+
297
+ ### 为什么选择运行时解析?
298
+
299
+ Schema-DSL 使用**运行时解析 DSL**,而非编译时构建(如 Zod),这是有意的设计选择:
300
+
301
+ #### ✅ 运行时解析的优势
302
+
303
+ 1. **完全动态** - 验证规则可以从配置文件、数据库动态加载
304
+ ```javascript
305
+ // 从配置读取规则
306
+ const rules = await db.findOne({ entity: 'user' });
307
+ const schema = dsl({
308
+ username: `string:${rules.min}-${rules.max}!`
309
+ });
310
+ ```
311
+
312
+ 2. **多租户支持** - 每个租户可以有不同的验证规则
313
+ ```javascript
314
+ // 租户A: 用户名3-32字符
315
+ // 租户B: 用户名5-50字符
316
+ function getTenantSchema(tenantId) {
317
+ const rules = tenantConfig[tenantId];
318
+ return dsl({
319
+ username: `string:${rules.min}-${rules.max}!`
320
+ });
321
+ }
322
+ ```
323
+
324
+ 3. **可序列化** - DSL 字符串可以存储、传输、共享
325
+ ```javascript
326
+ // 存储到数据库
327
+ await db.insert({
328
+ formId: 'register',
329
+ rules: { username: 'string:3-32!', email: 'email!' }
330
+ });
331
+
332
+ // 通过 API 传输
333
+ res.json({ validationRules: rules });
334
+
335
+ // 前后端共享规则
336
+ ```
337
+
338
+ 4. **低代码基础** - 支持可视化表单构建器
339
+ ```javascript
340
+ // 管理员在界面配置验证规则
341
+ const formBuilder = {
342
+ fields: [
343
+ { name: 'username', validation: 'string:3-32!' }
344
+ ]
345
+ };
346
+ ```
347
+
348
+ #### ⚠️ 性能权衡
349
+
350
+ S1 有效数据与 Zod 持平,S3 嵌套场景快约 28%,无效数据公平对比快 89x:
351
+
352
+ | 库名 | 性能 | 场景 |
353
+ |------|-----------|------|
354
+ | Ajv (raw) | 4.732M ops/s | 底层引擎,无 DSL 层 |
355
+ | **Schema-DSL** | **1.301M ops/s**(S1有效) | 全功能(DSL + i18n + coerce)|
356
+ | **Schema-DSL** | **1.205M ops/s**(S2 无效,均无 i18n)| 公平对比(均无 i18n)|
357
+ | Zod | 1.305M ops/s(S1有效)/ 13.49K(S2 无效)| 编译时构建,错误路径异常驱动 |
358
+ | Joi | 154K ops/s | 功能丰富 |
359
+
360
+ **结论**:
361
+ - ✅ S3 嵌套有效场景比 Zod 快 **28%**;S1 简单有效场景持平(差 <1%)
362
+ - ✅ 无效数据公平对比(均无 i18n)比 Zod 快 **89x**
363
+ - ✅ 内置缓存,热路径零解析开销
364
+
365
+ ### 适用场景
366
+
367
+ **✅ 选择 Schema-DSL**:
368
+ - 需要动态验证规则(配置驱动、多租户)
369
+ - 需要数据库 Schema 导出
370
+ - 快速开发原型
371
+ - 多语言 SaaS 系统
372
+
373
+ **⚠️ 考虑其他库**:
374
+ - TypeScript 项目需要强类型推断 → **Zod**
375
+ - 性能是第一优先级 → **Ajv** 或 **Zod**
376
+ - 静态验证规则 → **Zod**
377
+
378
+ ---
379
+
380
+ ## 🆘 常见问题
381
+
382
+ ### Q: String扩展和纯DSL有什么区别?
383
+
384
+ **A**:
385
+ - **纯DSL**: 适合简单字段,语法简洁
386
+ - **String扩展**: 适合复杂验证,支持链式调用
387
+
388
+ ```javascript
389
+ // 纯DSL(简单)
390
+ name: 'string:1-50!'
391
+
392
+ // String扩展(复杂)
393
+ email: 'email!'
394
+ .pattern(/custom/)
395
+ .messages({...})
396
+ ```
397
+
398
+ ### Q: 如何禁用String扩展?
399
+
400
+ **A**:
401
+ ```javascript
402
+ const { uninstallStringExtensions } = require('schema-dsl');
403
+ uninstallStringExtensions();
404
+ ```
405
+
406
+ ### Q: 支持TypeScript吗?
407
+
408
+ **A**: 支持!schema-dsl 提供完整的 TypeScript 类型定义。
409
+
410
+ ---
411
+
412
+ ## 🎉 恭喜!
413
+
414
+ 你已经掌握了 schema-dsl 的核心用法!
415
+
416
+ **核心要点**:
417
+ 1. ✅ DSL语法简洁直观
418
+ 2. ✅ String扩展强大灵活
419
+ 3. ✅ 80%用DSL,20%用扩展
420
+ 4. ✅ 字符串可以直接链式调用
421
+
422
+ **开始使用**: `npm install schema-dsl`
423
+
424
+ ---
425
+
426
+ ## 对应示例文件
427
+
428
+ **示例入口**: [quick-start.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/quick-start.ts)
429
+ **说明**: 覆盖快速上手中的 Hello World、String 扩展、用户注册示例,以及 `validate()` 与 `Validator.compile()` 的基础复用路径,可直接运行参考。
430
+
431
+ ---
432
+
433
+ **最后更新**: 2026-05-08
434
+
435
+