schema-dsl 1.2.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/CHANGELOG.md +87 -210
  2. package/README.md +391 -2249
  3. package/dist/DslBuilder-DQDN0ZxZ.d.cts +341 -0
  4. package/dist/DslBuilder-DkLaOo9Q.d.ts +341 -0
  5. package/dist/Validator-C7GsVQOH.d.cts +192 -0
  6. package/dist/Validator-hFWKGxir.d.ts +192 -0
  7. package/dist/index.cjs +6594 -0
  8. package/dist/index.d.cts +1145 -0
  9. package/dist/index.d.ts +1145 -0
  10. package/dist/index.js +6528 -0
  11. package/dist/plugin-CIKtTMtS.d.cts +246 -0
  12. package/dist/plugin-CIKtTMtS.d.ts +246 -0
  13. package/dist/plugins/custom-format.cjs +3802 -0
  14. package/dist/plugins/custom-format.d.cts +12 -0
  15. package/dist/plugins/custom-format.d.ts +12 -0
  16. package/dist/plugins/custom-format.js +3772 -0
  17. package/dist/plugins/custom-type-example.cjs +3795 -0
  18. package/dist/plugins/custom-type-example.d.cts +8 -0
  19. package/dist/plugins/custom-type-example.d.ts +8 -0
  20. package/dist/plugins/custom-type-example.js +3765 -0
  21. package/dist/plugins/custom-validator.cjs +146 -0
  22. package/dist/plugins/custom-validator.d.cts +10 -0
  23. package/dist/plugins/custom-validator.d.ts +10 -0
  24. package/dist/plugins/custom-validator.js +121 -0
  25. package/docs/FEATURE-INDEX.md +102 -68
  26. package/docs/add-custom-locale.md +48 -35
  27. package/docs/add-keyword.md +24 -0
  28. package/docs/api-reference.md +396 -154
  29. package/docs/api.md +13 -0
  30. package/docs/best-practices-project-structure.md +19 -10
  31. package/docs/best-practices.md +93 -53
  32. package/docs/cache-manager.md +23 -15
  33. package/docs/compile.md +45 -0
  34. package/docs/conditional-api.md +40 -11
  35. package/docs/custom-extensions-guide.md +80 -152
  36. package/docs/design-philosophy.md +76 -71
  37. package/docs/doc-index.md +324 -0
  38. package/docs/dsl-syntax.md +69 -19
  39. package/docs/dynamic-locale.md +24 -14
  40. package/docs/enum.md +12 -5
  41. package/docs/error-handling.md +53 -44
  42. package/docs/export-guide.md +47 -8
  43. package/docs/export-limitations.md +27 -11
  44. package/docs/faq.md +86 -67
  45. package/docs/frontend-i18n-guide.md +26 -12
  46. package/docs/i18n-user-guide.md +60 -47
  47. package/docs/i18n.md +51 -32
  48. package/docs/index.md +48 -0
  49. package/docs/json-schema-basics.md +40 -0
  50. package/docs/label-vs-description.md +12 -3
  51. package/docs/markdown-exporter.md +15 -6
  52. package/docs/mongodb-exporter.md +11 -4
  53. package/docs/multi-language.md +26 -0
  54. package/docs/multi-type-support.md +26 -33
  55. package/docs/mysql-exporter.md +9 -2
  56. package/docs/number-operators.md +12 -5
  57. package/docs/optional-marker-guide.md +28 -23
  58. package/docs/performance-guide.md +49 -0
  59. package/docs/plugin-system.md +205 -366
  60. package/docs/plugin-type-registration.md +34 -0
  61. package/docs/postgresql-exporter.md +9 -2
  62. package/docs/public/favicon.svg +5 -0
  63. package/docs/quick-start.md +37 -363
  64. package/docs/runtime-locale-support.md +20 -9
  65. package/docs/schema-helper.md +10 -5
  66. package/docs/schema-utils-advanced-issues.md +23 -0
  67. package/docs/schema-utils-best-practices.md +20 -0
  68. package/docs/schema-utils-chaining.md +7 -0
  69. package/docs/schema-utils.md +76 -42
  70. package/docs/security-checklist.md +20 -0
  71. package/docs/string-extensions.md +17 -9
  72. package/docs/troubleshooting.md +36 -21
  73. package/docs/type-converter.md +41 -50
  74. package/docs/type-reference.md +38 -15
  75. package/docs/typescript-guide.md +53 -42
  76. package/docs/union-type-guide.md +11 -1
  77. package/docs/union-types.md +10 -3
  78. package/docs/validate-async.md +36 -25
  79. package/docs/validate-batch.md +49 -0
  80. package/docs/validate-dsl-object-support.md +33 -28
  81. package/docs/validate.md +36 -16
  82. package/docs/validation-guide.md +25 -7
  83. package/docs/validator.md +39 -0
  84. package/package.json +85 -27
  85. package/plugins/custom-format.cjs +8 -0
  86. package/plugins/custom-type-example.cjs +8 -0
  87. package/plugins/custom-validator.cjs +8 -0
  88. package/src/adapters/DslAdapter.ts +111 -0
  89. package/src/adapters/index.ts +1 -0
  90. package/src/config/constants.ts +83 -0
  91. package/src/config/index.ts +2 -0
  92. package/src/config/patterns.ts +77 -0
  93. package/src/core/CacheManager.ts +159 -0
  94. package/src/core/ConditionalBuilder.ts +382 -0
  95. package/src/core/ConditionalRuntime.ts +28 -0
  96. package/src/core/ConditionalValidator.ts +255 -0
  97. package/src/core/DslBuilder.ts +677 -0
  98. package/src/core/ErrorCodes.ts +38 -0
  99. package/src/core/ErrorFormatter.ts +271 -0
  100. package/src/core/JSONSchemaCore.ts +65 -0
  101. package/src/core/Locale.ts +187 -0
  102. package/src/core/MessageTemplate.ts +42 -0
  103. package/src/core/ObjectDslBuilder.ts +64 -0
  104. package/src/core/PluginManager.ts +326 -0
  105. package/src/core/StringExtensions.ts +140 -0
  106. package/src/core/TemplateEngine.ts +44 -0
  107. package/src/core/Validator.ts +448 -0
  108. package/src/errors/I18nError.ts +159 -0
  109. package/src/errors/ValidationError.ts +105 -0
  110. package/src/exporters/BaseExporter.ts +60 -0
  111. package/src/exporters/MarkdownExporter.ts +305 -0
  112. package/src/exporters/MongoDBExporter.ts +126 -0
  113. package/src/exporters/MySQLExporter.ts +155 -0
  114. package/src/exporters/PostgreSQLExporter.ts +222 -0
  115. package/src/exporters/index.ts +18 -0
  116. package/src/index.ts +633 -0
  117. package/{lib/locales/en-US.js → src/locales/en-US.ts} +21 -37
  118. package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +63 -16
  119. package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +74 -27
  120. package/src/locales/index.ts +103 -0
  121. package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +59 -17
  122. package/src/locales/types.ts +156 -0
  123. package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +21 -38
  124. package/src/parser/ConstraintParser.ts +101 -0
  125. package/src/parser/DslParser.ts +470 -0
  126. package/src/parser/SchemaCompiler.ts +66 -0
  127. package/src/parser/TypeRegistry.ts +250 -0
  128. package/src/parser/index.ts +6 -0
  129. package/src/plugins/custom-format.ts +126 -0
  130. package/src/plugins/custom-type-example.ts +108 -0
  131. package/src/plugins/custom-validator.ts +140 -0
  132. package/src/types/conditional.ts +28 -0
  133. package/src/types/config.ts +59 -0
  134. package/src/types/dsl.ts +131 -0
  135. package/src/types/error.ts +60 -0
  136. package/src/types/index.ts +17 -0
  137. package/src/types/infer.ts +128 -0
  138. package/src/types/plugin.ts +58 -0
  139. package/src/types/safe-regex.d.ts +9 -0
  140. package/src/types/schema.ts +66 -0
  141. package/src/types/validate.ts +71 -0
  142. package/src/utils/SchemaHelper.ts +196 -0
  143. package/src/utils/SchemaUtils.ts +346 -0
  144. package/src/utils/TypeConverter.ts +215 -0
  145. package/src/utils/index.ts +10 -0
  146. package/src/validators/CustomKeywords.ts +477 -0
  147. package/.eslintignore +0 -11
  148. package/.eslintrc.json +0 -27
  149. package/CONTRIBUTING.md +0 -368
  150. package/STATUS.md +0 -491
  151. package/changelogs/v1.0.0.md +0 -328
  152. package/changelogs/v1.0.9.md +0 -367
  153. package/changelogs/v1.1.0.md +0 -389
  154. package/changelogs/v1.1.1.md +0 -308
  155. package/changelogs/v1.1.2.md +0 -183
  156. package/changelogs/v1.1.3.md +0 -161
  157. package/changelogs/v1.1.4.md +0 -432
  158. package/changelogs/v1.1.5.md +0 -493
  159. package/changelogs/v1.1.6.md +0 -211
  160. package/changelogs/v1.1.8.md +0 -376
  161. package/changelogs/v1.2.3.md +0 -124
  162. package/docs/INDEX.md +0 -252
  163. package/docs/issues-resolved-summary.md +0 -196
  164. package/docs/performance-benchmark-report.md +0 -179
  165. package/docs/performance-quick-reference.md +0 -123
  166. package/docs/user-questions-answered.md +0 -353
  167. package/docs/validation-rules-v1.0.2.md +0 -1608
  168. package/examples/README.md +0 -81
  169. package/examples/array-dsl-example.js +0 -227
  170. package/examples/conditional-example.js +0 -288
  171. package/examples/conditional-non-object.js +0 -129
  172. package/examples/conditional-validate-example.js +0 -321
  173. package/examples/custom-extension.js +0 -85
  174. package/examples/dsl-match-example.js +0 -74
  175. package/examples/dsl-style.js +0 -118
  176. package/examples/dynamic-locale-configuration.js +0 -348
  177. package/examples/dynamic-locale-example.js +0 -287
  178. package/examples/enum.examples.js +0 -324
  179. package/examples/export-demo.js +0 -130
  180. package/examples/express-integration.js +0 -376
  181. package/examples/i18n-error-handling-complete.js +0 -381
  182. package/examples/i18n-error-handling-quickstart.md +0 -0
  183. package/examples/i18n-error.examples.js +0 -181
  184. package/examples/i18n-full-demo.js +0 -301
  185. package/examples/i18n-memory-safety.examples.js +0 -268
  186. package/examples/markdown-export.js +0 -71
  187. package/examples/middleware-usage.js +0 -93
  188. package/examples/new-features-comparison.js +0 -315
  189. package/examples/password-reset/README.md +0 -153
  190. package/examples/password-reset/schema.js +0 -26
  191. package/examples/password-reset/test.js +0 -101
  192. package/examples/plugin-system.examples.js +0 -205
  193. package/examples/schema-utils-chaining.examples.js +0 -250
  194. package/examples/simple-example.js +0 -122
  195. package/examples/slug.examples.js +0 -179
  196. package/examples/string-extensions.js +0 -297
  197. package/examples/union-type-example.js +0 -127
  198. package/examples/union-types-example.js +0 -77
  199. package/examples/user-registration/README.md +0 -156
  200. package/examples/user-registration/routes.js +0 -92
  201. package/examples/user-registration/schema.js +0 -150
  202. package/examples/user-registration/server.js +0 -74
  203. package/index.d.ts +0 -3540
  204. package/index.js +0 -457
  205. package/index.mjs +0 -60
  206. package/lib/adapters/DslAdapter.js +0 -871
  207. package/lib/adapters/index.js +0 -20
  208. package/lib/config/constants.js +0 -286
  209. package/lib/config/patterns/common.js +0 -47
  210. package/lib/config/patterns/creditCard.js +0 -9
  211. package/lib/config/patterns/idCard.js +0 -9
  212. package/lib/config/patterns/index.js +0 -9
  213. package/lib/config/patterns/licensePlate.js +0 -4
  214. package/lib/config/patterns/passport.js +0 -4
  215. package/lib/config/patterns/phone.js +0 -9
  216. package/lib/config/patterns/postalCode.js +0 -5
  217. package/lib/core/CacheManager.js +0 -376
  218. package/lib/core/ConditionalBuilder.js +0 -503
  219. package/lib/core/DslBuilder.js +0 -1400
  220. package/lib/core/ErrorCodes.js +0 -233
  221. package/lib/core/ErrorFormatter.js +0 -445
  222. package/lib/core/JSONSchemaCore.js +0 -347
  223. package/lib/core/Locale.js +0 -130
  224. package/lib/core/MessageTemplate.js +0 -98
  225. package/lib/core/PluginManager.js +0 -448
  226. package/lib/core/StringExtensions.js +0 -240
  227. package/lib/core/Validator.js +0 -654
  228. package/lib/errors/I18nError.js +0 -328
  229. package/lib/errors/ValidationError.js +0 -191
  230. package/lib/exporters/MarkdownExporter.js +0 -420
  231. package/lib/exporters/MongoDBExporter.js +0 -162
  232. package/lib/exporters/MySQLExporter.js +0 -212
  233. package/lib/exporters/PostgreSQLExporter.js +0 -289
  234. package/lib/exporters/index.js +0 -24
  235. package/lib/locales/index.js +0 -8
  236. package/lib/utils/LRUCache.js +0 -174
  237. package/lib/utils/SchemaHelper.js +0 -240
  238. package/lib/utils/SchemaUtils.js +0 -445
  239. package/lib/utils/TypeConverter.js +0 -245
  240. package/lib/utils/index.js +0 -13
  241. package/lib/validators/CustomKeywords.js +0 -616
  242. 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
-