schema-dsl 1.2.5 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (243) hide show
  1. package/CHANGELOG.md +130 -238
  2. package/LICENSE +21 -21
  3. package/README.md +628 -2486
  4. package/dist/DslBuilder-BIgQOAXp.d.ts +343 -0
  5. package/dist/DslBuilder-CjHTucNQ.d.cts +343 -0
  6. package/dist/Validator-CllRdrY0.d.ts +192 -0
  7. package/dist/Validator-D6okG9tr.d.cts +192 -0
  8. package/dist/index.cjs +6640 -0
  9. package/dist/index.d.cts +1151 -0
  10. package/dist/index.d.ts +1151 -0
  11. package/dist/index.js +6574 -0
  12. package/dist/plugin-CIKtTMtS.d.cts +246 -0
  13. package/dist/plugin-CIKtTMtS.d.ts +246 -0
  14. package/dist/plugins/custom-format.cjs +3818 -0
  15. package/dist/plugins/custom-format.d.cts +12 -0
  16. package/dist/plugins/custom-format.d.ts +12 -0
  17. package/dist/plugins/custom-format.js +3788 -0
  18. package/dist/plugins/custom-type-example.cjs +3811 -0
  19. package/dist/plugins/custom-type-example.d.cts +8 -0
  20. package/dist/plugins/custom-type-example.d.ts +8 -0
  21. package/dist/plugins/custom-type-example.js +3781 -0
  22. package/dist/plugins/custom-validator.cjs +144 -0
  23. package/dist/plugins/custom-validator.d.cts +10 -0
  24. package/dist/plugins/custom-validator.d.ts +10 -0
  25. package/dist/plugins/custom-validator.js +119 -0
  26. package/docs/FEATURE-INDEX.md +553 -519
  27. package/docs/add-custom-locale.md +496 -483
  28. package/docs/add-keyword.md +24 -0
  29. package/docs/api-reference.md +1047 -805
  30. package/docs/api.md +13 -0
  31. package/docs/best-practices-project-structure.md +417 -408
  32. package/docs/best-practices.md +712 -672
  33. package/docs/cache-manager.md +344 -336
  34. package/docs/compile.md +45 -0
  35. package/docs/conditional-api.md +1307 -1278
  36. package/docs/custom-extensions-guide.md +339 -411
  37. package/docs/design-philosophy.md +606 -601
  38. package/docs/doc-index.md +324 -0
  39. package/docs/dsl-syntax.md +714 -664
  40. package/docs/dynamic-locale.md +608 -598
  41. package/docs/enum.md +482 -475
  42. package/docs/error-handling.md +1975 -1966
  43. package/docs/export-guide.md +501 -462
  44. package/docs/export-limitations.md +567 -551
  45. package/docs/faq.md +596 -577
  46. package/docs/frontend-i18n-guide.md +307 -293
  47. package/docs/i18n-user-guide.md +487 -474
  48. package/docs/i18n.md +476 -457
  49. package/docs/index.md +48 -0
  50. package/docs/json-schema-basics.md +40 -0
  51. package/docs/label-vs-description.md +271 -262
  52. package/docs/markdown-exporter.md +406 -397
  53. package/docs/mongodb-exporter.md +302 -295
  54. package/docs/multi-language.md +26 -0
  55. package/docs/multi-type-support.md +322 -329
  56. package/docs/mysql-exporter.md +280 -273
  57. package/docs/number-operators.md +449 -442
  58. package/docs/optional-marker-guide.md +326 -321
  59. package/docs/performance-guide.md +49 -0
  60. package/docs/plugin-system.md +381 -542
  61. package/docs/plugin-type-registration.md +34 -0
  62. package/docs/postgresql-exporter.md +311 -304
  63. package/docs/public/favicon.svg +5 -0
  64. package/docs/quick-start.md +435 -761
  65. package/docs/runtime-locale-support.md +532 -521
  66. package/docs/schema-helper.md +345 -340
  67. package/docs/schema-utils-advanced-issues.md +23 -0
  68. package/docs/schema-utils-best-practices.md +20 -0
  69. package/docs/schema-utils-chaining.md +150 -143
  70. package/docs/schema-utils.md +524 -490
  71. package/docs/security-checklist.md +20 -0
  72. package/docs/string-extensions.md +488 -480
  73. package/docs/troubleshooting.md +486 -471
  74. package/docs/type-converter.md +310 -319
  75. package/docs/type-reference.md +242 -219
  76. package/docs/typescript-guide.md +584 -573
  77. package/docs/union-type-guide.md +157 -147
  78. package/docs/union-types.md +284 -277
  79. package/docs/validate-async.md +491 -480
  80. package/docs/validate-batch.md +49 -0
  81. package/docs/validate-dsl-object-support.md +578 -573
  82. package/docs/validate.md +506 -486
  83. package/docs/validation-guide.md +502 -484
  84. package/docs/validator.md +39 -0
  85. package/package.json +131 -73
  86. package/plugins/custom-format.cjs +8 -0
  87. package/plugins/custom-type-example.cjs +8 -0
  88. package/plugins/custom-validator.cjs +8 -0
  89. package/src/adapters/DslAdapter.ts +111 -0
  90. package/src/adapters/index.ts +1 -0
  91. package/src/config/constants.ts +83 -0
  92. package/src/config/index.ts +2 -0
  93. package/src/config/patterns.ts +77 -0
  94. package/src/core/CacheManager.ts +169 -0
  95. package/src/core/ConditionalBuilder.ts +382 -0
  96. package/src/core/ConditionalRuntime.ts +28 -0
  97. package/src/core/ConditionalValidator.ts +255 -0
  98. package/src/core/DslBuilder.ts +687 -0
  99. package/src/core/ErrorCodes.ts +38 -0
  100. package/src/core/ErrorFormatter.ts +271 -0
  101. package/src/core/JSONSchemaCore.ts +65 -0
  102. package/src/core/Locale.ts +187 -0
  103. package/src/core/MessageTemplate.ts +42 -0
  104. package/src/core/ObjectDslBuilder.ts +64 -0
  105. package/src/core/PluginManager.ts +326 -0
  106. package/src/core/StringExtensions.ts +140 -0
  107. package/src/core/TemplateEngine.ts +44 -0
  108. package/src/core/Validator.ts +448 -0
  109. package/src/errors/I18nError.ts +159 -0
  110. package/src/errors/ValidationError.ts +105 -0
  111. package/src/exporters/BaseExporter.ts +60 -0
  112. package/src/exporters/MarkdownExporter.ts +305 -0
  113. package/src/exporters/MongoDBExporter.ts +126 -0
  114. package/src/exporters/MySQLExporter.ts +156 -0
  115. package/src/exporters/PostgreSQLExporter.ts +222 -0
  116. package/src/exporters/index.ts +18 -0
  117. package/src/index.ts +651 -0
  118. package/{lib/locales/en-US.js → src/locales/en-US.ts} +160 -176
  119. package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +160 -113
  120. package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +160 -113
  121. package/src/locales/index.ts +103 -0
  122. package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +160 -118
  123. package/src/locales/types.ts +156 -0
  124. package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +160 -177
  125. package/src/parser/ConstraintParser.ts +101 -0
  126. package/src/parser/DslParser.ts +470 -0
  127. package/src/parser/SchemaCompiler.ts +66 -0
  128. package/src/parser/TypeRegistry.ts +250 -0
  129. package/src/parser/index.ts +6 -0
  130. package/src/plugins/custom-format.ts +124 -0
  131. package/src/plugins/custom-type-example.ts +106 -0
  132. package/src/plugins/custom-validator.ts +138 -0
  133. package/src/types/conditional.ts +28 -0
  134. package/src/types/config.ts +59 -0
  135. package/src/types/dsl.ts +131 -0
  136. package/src/types/error.ts +60 -0
  137. package/src/types/index.ts +17 -0
  138. package/src/types/infer.ts +128 -0
  139. package/src/types/plugin.ts +58 -0
  140. package/src/types/safe-regex.d.ts +9 -0
  141. package/src/types/schema.ts +66 -0
  142. package/src/types/validate.ts +71 -0
  143. package/src/utils/SchemaHelper.ts +196 -0
  144. package/src/utils/SchemaUtils.ts +365 -0
  145. package/src/utils/TypeConverter.ts +215 -0
  146. package/src/utils/index.ts +10 -0
  147. package/src/validators/CustomKeywords.ts +477 -0
  148. package/.eslintignore +0 -11
  149. package/.eslintrc.json +0 -27
  150. package/CONTRIBUTING.md +0 -368
  151. package/STATUS.md +0 -491
  152. package/changelogs/v1.0.0.md +0 -328
  153. package/changelogs/v1.0.9.md +0 -367
  154. package/changelogs/v1.1.0.md +0 -389
  155. package/changelogs/v1.1.1.md +0 -308
  156. package/changelogs/v1.1.2.md +0 -183
  157. package/changelogs/v1.1.3.md +0 -161
  158. package/changelogs/v1.1.4.md +0 -432
  159. package/changelogs/v1.1.5.md +0 -493
  160. package/changelogs/v1.1.6.md +0 -211
  161. package/changelogs/v1.1.8.md +0 -376
  162. package/changelogs/v1.2.3.md +0 -124
  163. package/docs/INDEX.md +0 -252
  164. package/docs/issues-resolved-summary.md +0 -196
  165. package/docs/performance-benchmark-report.md +0 -179
  166. package/docs/performance-quick-reference.md +0 -123
  167. package/docs/user-questions-answered.md +0 -353
  168. package/docs/validation-rules-v1.0.2.md +0 -1608
  169. package/examples/README.md +0 -81
  170. package/examples/array-dsl-example.js +0 -227
  171. package/examples/conditional-example.js +0 -288
  172. package/examples/conditional-non-object.js +0 -129
  173. package/examples/conditional-validate-example.js +0 -321
  174. package/examples/custom-extension.js +0 -85
  175. package/examples/dsl-match-example.js +0 -74
  176. package/examples/dsl-style.js +0 -118
  177. package/examples/dynamic-locale-configuration.js +0 -348
  178. package/examples/dynamic-locale-example.js +0 -287
  179. package/examples/enum.examples.js +0 -324
  180. package/examples/export-demo.js +0 -130
  181. package/examples/express-integration.js +0 -376
  182. package/examples/i18n-error-handling-complete.js +0 -381
  183. package/examples/i18n-error-handling-quickstart.md +0 -0
  184. package/examples/i18n-error.examples.js +0 -181
  185. package/examples/i18n-full-demo.js +0 -301
  186. package/examples/i18n-memory-safety.examples.js +0 -268
  187. package/examples/markdown-export.js +0 -71
  188. package/examples/middleware-usage.js +0 -93
  189. package/examples/new-features-comparison.js +0 -315
  190. package/examples/password-reset/README.md +0 -153
  191. package/examples/password-reset/schema.js +0 -26
  192. package/examples/password-reset/test.js +0 -101
  193. package/examples/plugin-system.examples.js +0 -205
  194. package/examples/schema-utils-chaining.examples.js +0 -250
  195. package/examples/simple-example.js +0 -122
  196. package/examples/slug.examples.js +0 -179
  197. package/examples/string-extensions.js +0 -297
  198. package/examples/union-type-example.js +0 -127
  199. package/examples/union-types-example.js +0 -77
  200. package/examples/user-registration/README.md +0 -156
  201. package/examples/user-registration/routes.js +0 -92
  202. package/examples/user-registration/schema.js +0 -150
  203. package/examples/user-registration/server.js +0 -74
  204. package/index.d.ts +0 -3658
  205. package/index.js +0 -475
  206. package/index.mjs +0 -60
  207. package/lib/adapters/DslAdapter.js +0 -995
  208. package/lib/adapters/index.js +0 -20
  209. package/lib/config/constants.js +0 -286
  210. package/lib/config/patterns/common.js +0 -47
  211. package/lib/config/patterns/creditCard.js +0 -9
  212. package/lib/config/patterns/idCard.js +0 -9
  213. package/lib/config/patterns/index.js +0 -9
  214. package/lib/config/patterns/licensePlate.js +0 -4
  215. package/lib/config/patterns/passport.js +0 -4
  216. package/lib/config/patterns/phone.js +0 -9
  217. package/lib/config/patterns/postalCode.js +0 -5
  218. package/lib/core/CacheManager.js +0 -376
  219. package/lib/core/ConditionalBuilder.js +0 -503
  220. package/lib/core/DslBuilder.js +0 -1589
  221. package/lib/core/ErrorCodes.js +0 -233
  222. package/lib/core/ErrorFormatter.js +0 -445
  223. package/lib/core/JSONSchemaCore.js +0 -347
  224. package/lib/core/Locale.js +0 -130
  225. package/lib/core/MessageTemplate.js +0 -98
  226. package/lib/core/PluginManager.js +0 -448
  227. package/lib/core/StringExtensions.js +0 -240
  228. package/lib/core/Validator.js +0 -654
  229. package/lib/errors/I18nError.js +0 -328
  230. package/lib/errors/ValidationError.js +0 -191
  231. package/lib/exporters/MarkdownExporter.js +0 -420
  232. package/lib/exporters/MongoDBExporter.js +0 -162
  233. package/lib/exporters/MySQLExporter.js +0 -212
  234. package/lib/exporters/PostgreSQLExporter.js +0 -289
  235. package/lib/exporters/index.js +0 -24
  236. package/lib/locales/index.js +0 -8
  237. package/lib/utils/LRUCache.js +0 -174
  238. package/lib/utils/SchemaHelper.js +0 -240
  239. package/lib/utils/SchemaUtils.js +0 -445
  240. package/lib/utils/TypeConverter.js +0 -245
  241. package/lib/utils/index.js +0 -13
  242. package/lib/validators/CustomKeywords.js +0 -616
  243. package/lib/validators/index.js +0 -11
@@ -1,761 +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
- ---
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**: 支持!SchemaI-DSL提供完整的TypeScript类型定义。
417
-
418
- ---
419
-
420
- ## 🎉 恭喜!
421
-
422
- 你已经掌握了SchemaI-DSL的核心用法!
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**: 支持!SchemaI-DSL提供完整的TypeScript类型定义。
741
-
742
- ---
743
-
744
- ## 🎉 恭喜!
745
-
746
- 你已经掌握了SchemaI-DSL的核心用法!
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
-
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
+