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,179 +0,0 @@
1
- /**
2
- * slug 类型验证示例
3
- *
4
- * slug 用于 URL 友好的字符串,只能包含:
5
- * - 小写字母 (a-z)
6
- * - 数字 (0-9)
7
- * - 连字符 (-)
8
- *
9
- * 格式规则:
10
- * - 必须以字母或数字开头
11
- * - 必须以字母或数字结尾
12
- * - 中间可以有连字符,但不能连续
13
- */
14
-
15
- const { dsl, validate } = require('../index');
16
-
17
- // ========== 示例 1: 基础用法 ==========
18
- console.log('\n========== 示例 1: 基础 slug 验证 ==========');
19
-
20
- const schema1 = dsl({
21
- slug: 'slug!'
22
- });
23
-
24
- console.log('✅ 有效的 slug:');
25
- console.log(' my-blog-post:', validate(schema1, { slug: 'my-blog-post' }).valid);
26
- console.log(' hello-world:', validate(schema1, { slug: 'hello-world' }).valid);
27
- console.log(' post-123:', validate(schema1, { slug: 'post-123' }).valid);
28
- console.log(' article:', validate(schema1, { slug: 'article' }).valid);
29
-
30
- console.log('\n❌ 无效的 slug:');
31
- console.log(' My-Blog-Post:', validate(schema1, { slug: 'My-Blog-Post' }).valid); // 大写
32
- console.log(' hello_world:', validate(schema1, { slug: 'hello_world' }).valid); // 下划线
33
- console.log(' -hello:', validate(schema1, { slug: '-hello' }).valid); // 开头连字符
34
- console.log(' hello-:', validate(schema1, { slug: 'hello-' }).valid); // 结尾连字符
35
- console.log(' hello--world:', validate(schema1, { slug: 'hello--world' }).valid); // 连续连字符
36
- console.log(' hello world:', validate(schema1, { slug: 'hello world' }).valid); // 空格
37
-
38
- // ========== 示例 2: DSL 字符串语法 ==========
39
- console.log('\n========== 示例 2: DSL 字符串语法 ==========');
40
-
41
- const schema2 = dsl({
42
- articleSlug: 'slug:3-100!' // slug + 长度限制
43
- });
44
-
45
- console.log('✅ 3-100字符的 slug:');
46
- console.log(' abc:', validate(schema2, { articleSlug: 'abc' }).valid);
47
- console.log(' my-long-article-title-with-many-words:',
48
- validate(schema2, { articleSlug: 'my-long-article-title-with-many-words' }).valid);
49
-
50
- console.log('\n❌ 长度不符:');
51
- console.log(' ab:', validate(schema2, { articleSlug: 'ab' }).valid); // 太短
52
-
53
- // ========== 示例 3: 链式调用 ==========
54
- console.log('\n========== 示例 3: 链式调用 ==========');
55
-
56
- const schema3 = dsl({
57
- pageSlug: 'string!'.slug().label('页面别名')
58
- });
59
-
60
- console.log('✅ 链式调用验证:');
61
- console.log(' about-us:', validate(schema3, { pageSlug: 'about-us' }).valid);
62
- console.log(' contact:', validate(schema3, { pageSlug: 'contact' }).valid);
63
-
64
- // ========== 示例 4: 实际应用场景 ==========
65
- console.log('\n========== 示例 4: 博客文章Schema ==========');
66
-
67
- const blogPostSchema = dsl({
68
- title: 'string:1-200!',
69
- slug: 'slug:3-100!',
70
- author: 'string!',
71
- content: 'string:10-!',
72
- tags: 'array<slug>', // slug 数组
73
- publishedAt: 'datetime'
74
- });
75
-
76
- const validPost = {
77
- title: 'Getting Started with Node.js',
78
- slug: 'getting-started-with-nodejs',
79
- author: 'John Doe',
80
- content: 'This is a comprehensive guide to Node.js...',
81
- tags: ['nodejs', 'javascript', 'backend'],
82
- publishedAt: '2025-12-31T10:00:00Z'
83
- };
84
-
85
- console.log('✅ 有效的博客文章:', validate(blogPostSchema, validPost).valid);
86
-
87
- const invalidPost = {
88
- title: 'Invalid Post',
89
- slug: 'Invalid Slug!', // ❌ 包含大写和特殊字符
90
- author: 'Jane',
91
- content: 'Short content',
92
- tags: ['Node.js', 'JavaScript'], // ❌ 标签包含大写
93
- publishedAt: '2025-12-31T10:00:00Z'
94
- };
95
-
96
- const result = validate(blogPostSchema, invalidPost);
97
- console.log('\n❌ 无效的博客文章:', result.valid);
98
- if (!result.valid) {
99
- console.log('错误信息:');
100
- result.errors.forEach(err => {
101
- console.log(` - ${err.path}: ${err.message}`);
102
- });
103
- }
104
-
105
- // ========== 示例 5: URL 生成应用 ==========
106
- console.log('\n========== 示例 5: 自动生成 slug ==========');
107
-
108
- function generateSlug(title) {
109
- return title
110
- .toLowerCase()
111
- .replace(/[^a-z0-9]+/g, '-') // 替换非字母数字为连字符
112
- .replace(/^-+|-+$/g, ''); // 移除首尾连字符
113
- }
114
-
115
- const titles = [
116
- 'Hello World!',
117
- 'Getting Started with Node.js',
118
- 'Top 10 JavaScript Tips & Tricks',
119
- '2025年的技术趋势'
120
- ];
121
-
122
- const urlSchema = dsl({ slug: 'slug!' });
123
-
124
- console.log('标题 → slug 转换:');
125
- titles.forEach(title => {
126
- const slug = generateSlug(title);
127
- const isValid = validate(urlSchema, { slug }).valid;
128
- console.log(` "${title}"`);
129
- console.log(` → "${slug}" ${isValid ? '✅' : '❌'}`);
130
- });
131
-
132
- // ========== 示例 6: 多语言支持 ==========
133
- console.log('\n========== 示例 6: 多语言错误消息 ==========');
134
-
135
- const { Validator } = require('../index');
136
- const validator = new Validator();
137
-
138
- const schema6 = dsl({ slug: 'slug!' });
139
-
140
- // 中文
141
- const resultCN = validator.validate(schema6, { slug: 'Invalid Slug!' }, { locale: 'zh-CN' });
142
- console.log('中文错误:', resultCN.errors[0]?.message);
143
-
144
- // 英文
145
- const resultEN = validator.validate(schema6, { slug: 'Invalid Slug!' }, { locale: 'en-US' });
146
- console.log('英文错误:', resultEN.errors[0]?.message);
147
-
148
- // 西班牙语
149
- const resultES = validator.validate(schema6, { slug: 'Invalid Slug!' }, { locale: 'es-ES' });
150
- console.log('西班牙语错误:', resultES.errors[0]?.message);
151
-
152
- // ========== 示例 7: 常见错误 ==========
153
- console.log('\n========== 示例 7: 常见 slug 错误 ==========');
154
-
155
- const testCases = [
156
- { slug: 'valid-slug-123', expected: true, reason: '✅ 正确格式' },
157
- { slug: 'Valid-Slug', expected: false, reason: '❌ 包含大写字母' },
158
- { slug: 'hello_world', expected: false, reason: '❌ 包含下划线' },
159
- { slug: 'hello world', expected: false, reason: '❌ 包含空格' },
160
- { slug: '-hello', expected: false, reason: '❌ 以连字符开头' },
161
- { slug: 'hello-', expected: false, reason: '❌ 以连字符结尾' },
162
- { slug: 'hello--world', expected: false, reason: '❌ 连续连字符' },
163
- { slug: 'hello.world', expected: false, reason: '❌ 包含点号' },
164
- { slug: '123-456', expected: true, reason: '✅ 纯数字+连字符' },
165
- { slug: 'a', expected: true, reason: '✅ 单个字母' },
166
- { slug: '1', expected: true, reason: '✅ 单个数字' }
167
- ];
168
-
169
- const testSchema = dsl({ slug: 'slug!' });
170
-
171
- console.log('测试用例:');
172
- testCases.forEach(({ slug, expected, reason }) => {
173
- const result = validate(testSchema, { slug });
174
- const passed = result.valid === expected;
175
- console.log(` ${passed ? '✅' : '❌'} "${slug}" - ${reason}`);
176
- });
177
-
178
- console.log('\n========== 所有示例完成 ==========');
179
-
@@ -1,297 +0,0 @@
1
- /**
2
- * String 扩展完整示例 v2.0.1
3
- *
4
- * 展示字符串直接链式调用所有方法
5
- * 无需 dsl() 包裹,语法更简洁
6
- */
7
-
8
- const { dsl, Validator } = require('../index');
9
-
10
- console.log('========== String 扩展特性展示 ==========\n');
11
-
12
- // ========== 1. 基础链式调用 ==========
13
-
14
- console.log('1️⃣ 基础链式调用');
15
-
16
- const basicSchema = dsl({
17
- // 最简单:纯DSL字符串
18
- name: 'string:1-50!',
19
-
20
- // ✨ String扩展:添加标签
21
- email: 'email!'.label('邮箱地址'),
22
-
23
- // ✨ String扩展:添加描述
24
- website: 'url'.description('个人主页'),
25
-
26
- // ✨ String扩展:设置默认值
27
- language: 'en|zh|ja'.default('zh')
28
- });
29
-
30
- console.log('基础Schema:', JSON.stringify(basicSchema, null, 2));
31
-
32
- // ========== 2. 正则验证 + 自定义消息 ==========
33
-
34
- console.log('\n2️⃣ 正则验证 + 自定义消息');
35
-
36
- const regexSchema = dsl({
37
- // ✨ 用户名:正则 + 消息
38
- username: 'string:3-32!'
39
- .pattern(/^[a-zA-Z0-9_]+$/)
40
- .messages({
41
- 'pattern': '只能包含字母、数字和下划线',
42
- 'min': '用户名至少3个字符',
43
- 'max': '用户名最多32个字符'
44
- })
45
- .label('用户名'),
46
-
47
- // ✨ 密码:复杂正则
48
- password: 'string:8-64!'
49
- .pattern(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).+$/)
50
- .messages({
51
- 'pattern': '密码必须包含大小写字母、数字和特殊字符'
52
- })
53
- .label('密码'),
54
-
55
- // ✨ 手机号:中国手机号格式
56
- phone: 'string:11!'
57
- .pattern(/^1[3-9]\d{9}$/)
58
- .messages({
59
- 'pattern': '请输入有效的中国手机号'
60
- })
61
- .label('手机号')
62
- });
63
-
64
- console.log('正则验证Schema:', JSON.stringify(regexSchema.properties.username, null, 2));
65
-
66
- // ========== 3. 完整的表单验证 ==========
67
-
68
- console.log('\n3️⃣ 完整的表单验证示例');
69
-
70
- const formSchema = dsl({
71
- // ✨ 邮箱
72
- email: 'email!'
73
- .label('邮箱地址')
74
- .description('用于登录和接收通知')
75
- .messages({
76
- 'format': '请输入有效的邮箱地址'
77
- }),
78
-
79
- // ✨ 昵称
80
- nickname: 'string:2-20!'
81
- .label('昵称')
82
- .description('显示在个人资料页面'),
83
-
84
- // ✨ 个人简介
85
- bio: 'string:500'
86
- .label('个人简介')
87
- .description('告诉大家你的故事'),
88
-
89
- // ✨ 社交媒体链接
90
- twitter: 'url'
91
- .pattern(/^https?:\/\/(www\.)?twitter\.com\//)
92
- .label('Twitter链接')
93
- .messages({
94
- 'pattern': '请输入有效的Twitter链接'
95
- }),
96
-
97
- github: 'url'
98
- .pattern(/^https?:\/\/(www\.)?github\.com\//)
99
- .label('GitHub链接')
100
- .messages({
101
- 'pattern': '请输入有效的GitHub链接'
102
- }),
103
-
104
- // 简单字段(无需链式)
105
- age: 'number:18-120',
106
- gender: 'male|female|other',
107
- country: 'string:2-50'
108
- });
109
-
110
- console.log('表单Schema字段数:', Object.keys(formSchema.properties).length);
111
-
112
- // ========== 4. 验证数据 ==========
113
-
114
- console.log('\n4️⃣ 数据验证');
115
-
116
- const { validate } = require('../index');
117
-
118
- const testData = {
119
- email: 'user@example.com',
120
- nickname: '张三',
121
- bio: '全栈开发工程师,热爱开源',
122
- twitter: 'https://twitter.com/username',
123
- github: 'https://github.com/username',
124
- age: 25,
125
- gender: 'male',
126
- country: '中国'
127
- };
128
-
129
- const result = validate(formSchema, testData);
130
- console.log('验证结果:', result.valid ? '✅ 通过' : '❌ 失败');
131
- if (!result.valid) {
132
- console.log('错误:', result.errors);
133
- }
134
-
135
- // ========== 5. 对比语法 ==========
136
-
137
- console.log('\n5️⃣ 语法对比');
138
-
139
- console.log('\n❌ v1.0(需要 dsl() 包裹):');
140
- console.log(`
141
- const schema = {
142
- email: dsl('email!')
143
- .pattern(/custom/)
144
- .messages({ ... })
145
- .label('邮箱地址')
146
- };
147
- `);
148
-
149
- console.log('✅ v2.0.1(字符串直接链式):');
150
- console.log(`
151
- const schema = {
152
- email: 'email!'
153
- .pattern(/custom/)
154
- .messages({ ... })
155
- .label('邮箱地址')
156
- };
157
- `);
158
-
159
- console.log('💡 减少字符数: 5个字符 (dsl())');
160
- console.log('💡 更直观: 字符串直接调用方法');
161
- console.log('💡 更简洁: 符合自然语言习惯');
162
-
163
- // ========== 6. 所有可用方法 ==========
164
-
165
- console.log('\n6️⃣ String扩展所有可用方法');
166
-
167
- const allMethods = `
168
- String.prototype 扩展方法:
169
-
170
- 1. .pattern(regex, message?) - 添加正则验证
171
- 2. .label(text) - 设置字段标签
172
- 3. .messages(obj) - 自定义错误消息
173
- 4. .description(text) - 设置描述
174
- 5. .custom(validator) - 自定义验证器
175
- 6. .when(field, options) - 条件验证
176
- 7. .default(value) - 设置默认值
177
- 8. .toSchema() - 转为JSON Schema
178
-
179
- 使用示例:
180
- 'string:3-32!'
181
- .pattern(/^\\w+$/) // 正则
182
- .label('用户名') // 标签
183
- .messages({...}) // 消息
184
- .description('登录名') // 描述
185
- .default('guest') // 默认值
186
- `;
187
-
188
- console.log(allMethods);
189
-
190
- // ========== 7. 高级用法:自定义验证器 ==========
191
-
192
- console.log('7️⃣ 高级用法:自定义验证器');
193
-
194
- // 模拟异步用户名检查
195
- async function checkUsernameExists(username) {
196
- // 模拟数据库查询
197
- const existingUsers = ['admin', 'root', 'test'];
198
- return existingUsers.includes(username);
199
- }
200
-
201
- const advancedSchema = dsl({
202
- username: 'string:3-32!'
203
- .pattern(/^[a-zA-Z0-9_]+$/)
204
- .custom(async (value) => {
205
- const exists = await checkUsernameExists(value);
206
- if (exists) {
207
- return {
208
- error: 'username.exists',
209
- message: '用户名已被占用'
210
- };
211
- }
212
- return true;
213
- })
214
- .label('用户名')
215
- });
216
-
217
- console.log('✅ 自定义验证器已添加(异步检查用户名是否存在)');
218
-
219
- // ========== 8. 嵌套对象中使用 ==========
220
-
221
- console.log('\n8️⃣ 嵌套对象中使用');
222
-
223
- const nestedSchema = dsl({
224
- user: {
225
- // ✨ 第一层嵌套
226
- profile: {
227
- name: 'string:1-50!'.label('姓名'),
228
- avatar: 'url'.label('头像URL'),
229
- // ✨ 第二层嵌套
230
- social: {
231
- twitter: 'url'
232
- .pattern(/twitter\.com/)
233
- .label('Twitter'),
234
- github: 'url'
235
- .pattern(/github\.com/)
236
- .label('GitHub')
237
- }
238
- }
239
- }
240
- });
241
-
242
- console.log('✅ 嵌套对象中String扩展完美支持');
243
- console.log('嵌套层级:', '3层(user → profile → social)');
244
-
245
- // ========== 9. 性能对比 ==========
246
-
247
- console.log('\n9️⃣ 性能测试');
248
-
249
- const iterations = 10000;
250
-
251
- // 测试1: 纯DSL
252
- console.time('纯DSL');
253
- for (let i = 0; i < iterations; i++) {
254
- dsl({
255
- name: 'string:1-50!',
256
- email: 'email!'
257
- });
258
- }
259
- console.timeEnd('纯DSL');
260
-
261
- // 测试2: String扩展
262
- console.time('String扩展');
263
- for (let i = 0; i < iterations; i++) {
264
- dsl({
265
- name: 'string:1-50!'.label('姓名'),
266
- email: 'email!'.label('邮箱')
267
- });
268
- }
269
- console.timeEnd('String扩展');
270
-
271
- console.log('✅ String扩展性能开销极小(<5%)');
272
-
273
- // ========== 总结 ==========
274
-
275
- console.log('\n========== 总结 ==========');
276
- console.log(`
277
- ✨ SchemaIO v2.0.1 String扩展特性:
278
-
279
- 1. ✅ 字符串直接链式调用
280
- 2. ✅ 无需 dsl() 包裹
281
- 3. ✅ 支持所有DslBuilder方法
282
- 4. ✅ 支持嵌套对象
283
- 5. ✅ 支持自定义验证器
284
- 6. ✅ 性能开销极小
285
- 7. ✅ 100%向后兼容
286
-
287
- 💡 推荐用法:
288
- - 简单字段:纯DSL字符串
289
- - 复杂字段:String扩展链式调用
290
- - 80%用DSL,20%用扩展
291
-
292
- 🎉 SchemaIO v2.0.1 - 最简洁的验证库!
293
- `);
294
-
295
- console.log('\n✅ String扩展示例运行完成!');
296
-
297
-
@@ -1,127 +0,0 @@
1
- /**
2
- * 联合类型验证示例
3
- *
4
- * 使用 .pattern() + .messages() 实现一个字段支持多种格式
5
- */
6
-
7
- const { dsl, validate } = require('../index');
8
-
9
- console.log('========================================');
10
- console.log('联合类型验证示例 - 使用 .pattern()');
11
- console.log('========================================\n');
12
-
13
- // ========================================
14
- // 示例1:邮箱或手机号(使用多语言 key)
15
- // ========================================
16
- console.log('【示例1】邮箱或手机号 - 多语言支持');
17
- console.log('----------------------------');
18
-
19
- const schema1 = dsl({
20
- name: 'string:1-50!',
21
- contact: dsl('string!')
22
- .pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
23
- .messages({ pattern: 'pattern.emailOrPhone' }) // 🌍 使用多语言 key
24
- .label('联系方式')
25
- });
26
-
27
- const testData1 = [
28
- { name: '张三', contact: 'zhangsan@example.com' },
29
- { name: '李四', contact: '13800138000' },
30
- { name: '王五', contact: 'invalid' }
31
- ];
32
-
33
- // 中文验证
34
- console.log('🇨🇳 中文错误消息:');
35
- testData1.forEach((data) => {
36
- const result = validate(schema1, data, { locale: 'zh-CN' });
37
- console.log(` ${data.name} (${data.contact}):`, result.valid ? '✅ 通过' : '❌ 失败');
38
- if (!result.valid) {
39
- console.log(` 错误: ${result.errors[0].message}`);
40
- }
41
- });
42
-
43
- // 英文验证
44
- console.log('\n🇺🇸 英文错误消息:');
45
- testData1.forEach((data) => {
46
- const result = validate(schema1, data, { locale: 'en-US' });
47
- console.log(` ${data.name} (${data.contact}):`, result.valid ? '✅ Pass' : '❌ Fail');
48
- if (!result.valid) {
49
- console.log(` Error: ${result.errors[0].message}`);
50
- }
51
- });
52
-
53
- console.log('');
54
-
55
- // ========================================
56
- // 示例2:用户登录(用户名或邮箱)- 多语言
57
- // ========================================
58
- console.log('【示例2】用户登录(用户名或邮箱)- 多语言');
59
- console.log('----------------------------');
60
-
61
- const loginSchema = dsl({
62
- username: dsl('string:3-32!')
63
- .pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|[a-zA-Z0-9_]+)$/)
64
- .messages({ pattern: 'pattern.usernameOrEmail' }) // 🌍 多语言 key
65
- .label('用户名'),
66
- password: 'string:8-32!'
67
- });
68
-
69
- const loginTest = { username: 'invalid!@#', password: '12345678' };
70
-
71
- console.log('🇨🇳 中文:');
72
- const r1 = validate(loginSchema, loginTest, { locale: 'zh-CN' });
73
- console.log(` ${loginTest.username}:`, r1.valid ? '✅' : `❌ ${r1.errors[0].message}`);
74
-
75
- console.log('🇺🇸 英文:');
76
- const r2 = validate(loginSchema, loginTest, { locale: 'en-US' });
77
- console.log(` ${loginTest.username}:`, r2.valid ? '✅' : `❌ ${r2.errors[0].message}`);
78
-
79
- console.log('');
80
-
81
- // ========================================
82
- // 示例3:URL(http 或 https)- 多语言
83
- // ========================================
84
- console.log('【示例3】URL(http 或 https)- 多语言');
85
- console.log('----------------------------');
86
-
87
- const urlSchema = dsl({
88
- website: dsl('string!')
89
- .pattern(/^https?:\/\/.+$/)
90
- .messages({ pattern: 'pattern.httpOrHttps' }) // 🌍 多语言 key
91
- .label('网站地址')
92
- });
93
-
94
- const urlTest = { website: 'ftp://example.com' };
95
-
96
- console.log('🇨🇳 中文:');
97
- const u1 = validate(urlSchema, urlTest, { locale: 'zh-CN' });
98
- console.log(` ${urlTest.website}:`, u1.valid ? '✅' : `❌ ${u1.errors[0].message}`);
99
-
100
- console.log('🇺🇸 英文:');
101
- const u2 = validate(urlSchema, urlTest, { locale: 'en-US' });
102
- console.log(` ${urlTest.website}:`, u2.valid ? '✅' : `❌ ${u2.errors[0].message}`);
103
-
104
- console.log('');
105
-
106
- // ========================================
107
- // 示例4:直接写错误消息(不使用多语言)
108
- // ========================================
109
- console.log('【示例4】直接写错误消息(不使用多语言)');
110
- console.log('----------------------------');
111
-
112
- const simpleSchema = dsl({
113
- contact: dsl('string!')
114
- .pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
115
- .messages({ pattern: '必须是邮箱或手机号' }) // 直接写死
116
- });
117
-
118
- const result = validate(simpleSchema, { contact: 'invalid' });
119
- console.log('invalid:', result.valid ? '✅' : `❌ ${result.errors[0].message}`);
120
-
121
- console.log('');
122
-
123
- console.log('========================================');
124
- console.log('示例运行完成!');
125
- console.log('多语言测试成功!🎉');
126
- console.log('========================================');
127
-
@@ -1,77 +0,0 @@
1
- /**
2
- * 跨类型联合验证示例
3
- *
4
- * 演示如何使用 types: 语法实现跨类型联合验证
5
- */
6
-
7
- const { dsl, validate, DslBuilder, PluginManager } = require('../index');
8
-
9
- console.log('='.repeat(60));
10
- console.log('跨类型联合验证 - types: 语法示例');
11
- console.log('='.repeat(60));
12
-
13
- // ========== 示例1:基础联合类型 ==========
14
- console.log('\n【示例1】基础联合类型:string|number');
15
- const schema1 = dsl({
16
- value: 'types:string|number'
17
- });
18
-
19
- console.log('✓ 字符串:', validate(schema1, { value: 'hello' }).valid);
20
- console.log('✓ 数字:', validate(schema1, { value: 123 }).valid);
21
- console.log('✗ 布尔:', validate(schema1, { value: true }).valid);
22
-
23
- // ========== 示例2:带约束的联合类型 ==========
24
- console.log('\n【示例2】带约束:string:3-10|number:0-100');
25
- const schema2 = dsl({
26
- value: 'types:string:3-10|number:0-100!'
27
- });
28
-
29
- console.log('✓ 字符串(abc):', validate(schema2, { value: 'abc' }).valid);
30
- console.log('✓ 数字(50):', validate(schema2, { value: 50 }).valid);
31
- console.log('✗ 字符串太短(ab):', validate(schema2, { value: 'ab' }).valid);
32
- console.log('✗ 数字超范围(101):', validate(schema2, { value: 101 }).valid);
33
-
34
- // ========== 示例3:使用插件自定义类型 ==========
35
- console.log('\n【示例3】使用插件自定义类型');
36
-
37
- // 加载custom-format插件
38
- const customFormatPlugin = require('../plugins/custom-format');
39
- const pluginManager = new PluginManager();
40
- pluginManager.register(customFormatPlugin);
41
- pluginManager.install(require('../index'));
42
-
43
- const schema3 = dsl({
44
- contact: 'types:email|phone-cn|qq!'
45
- });
46
-
47
- console.log('✓ 邮箱:', validate(schema3, { contact: 'user@example.com' }).valid);
48
- console.log('✓ 手机号:', validate(schema3, { contact: '13800138000' }).valid);
49
- console.log('✓ QQ号:', validate(schema3, { contact: '10000' }).valid);
50
- console.log('✗ 无效格式:', validate(schema3, { contact: 'invalid' }).valid);
51
-
52
- // ========== 示例4:复杂场景 - 用户注册表单 ==========
53
- console.log('\n【示例4】实际场景:用户注册表单');
54
-
55
- const registerSchema = dsl({
56
- username: 'string:3-20!',
57
- password: 'string:8-20!',
58
- contact: 'types:email|phone-cn!', // 邮箱或手机号
59
- age: 'types:integer:1-150|null', // 年龄或null
60
- referralCode: 'types:string:6|null' // 推荐码(6位)或null
61
- });
62
-
63
- const testData = {
64
- username: 'john_doe',
65
- password: 'Pass1234',
66
- contact: 'john@example.com',
67
- age: 25,
68
- referralCode: 'ABC123'
69
- };
70
-
71
- const result = validate(registerSchema, testData);
72
- console.log('✓ 完整表单验证:', result.valid);
73
-
74
- console.log('\n' + '='.repeat(60));
75
- console.log('示例执行完成!');
76
- console.log('='.repeat(60));
77
-