schema-dsl 1.0.9 → 1.1.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 (47) hide show
  1. package/CHANGELOG.md +325 -2
  2. package/README.md +419 -189
  3. package/STATUS.md +65 -3
  4. package/docs/FEATURE-INDEX.md +1 -1
  5. package/docs/best-practices.md +3 -3
  6. package/docs/cache-manager.md +1 -1
  7. package/docs/conditional-api.md +1278 -0
  8. package/docs/dsl-syntax.md +1 -1
  9. package/docs/dynamic-locale.md +2 -2
  10. package/docs/error-handling.md +2 -2
  11. package/docs/export-guide.md +2 -2
  12. package/docs/export-limitations.md +3 -3
  13. package/docs/faq.md +6 -6
  14. package/docs/frontend-i18n-guide.md +1 -1
  15. package/docs/mongodb-exporter.md +3 -3
  16. package/docs/multi-type-support.md +12 -2
  17. package/docs/mysql-exporter.md +1 -1
  18. package/docs/plugin-system.md +4 -4
  19. package/docs/postgresql-exporter.md +1 -1
  20. package/docs/quick-start.md +4 -4
  21. package/docs/troubleshooting.md +2 -2
  22. package/docs/type-reference.md +5 -5
  23. package/docs/typescript-guide.md +5 -6
  24. package/docs/union-type-guide.md +147 -0
  25. package/docs/union-types.md +277 -0
  26. package/docs/validate-async.md +1 -1
  27. package/examples/array-dsl-example.js +1 -1
  28. package/examples/conditional-example.js +288 -0
  29. package/examples/conditional-non-object.js +129 -0
  30. package/examples/conditional-validate-example.js +321 -0
  31. package/examples/i18n-error.examples.js +181 -0
  32. package/examples/union-type-example.js +127 -0
  33. package/examples/union-types-example.js +77 -0
  34. package/index.d.ts +655 -7
  35. package/index.js +54 -3
  36. package/lib/adapters/DslAdapter.js +14 -5
  37. package/lib/core/ConditionalBuilder.js +503 -0
  38. package/lib/core/DslBuilder.js +113 -0
  39. package/lib/core/Locale.js +13 -8
  40. package/lib/core/Validator.js +250 -2
  41. package/lib/errors/I18nError.js +222 -0
  42. package/lib/locales/en-US.js +39 -0
  43. package/lib/locales/es-ES.js +4 -0
  44. package/lib/locales/fr-FR.js +4 -0
  45. package/lib/locales/ja-JP.js +9 -0
  46. package/lib/locales/zh-CN.js +39 -0
  47. package/package.json +3 -1
@@ -0,0 +1,127 @@
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
+
@@ -0,0 +1,77 @@
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
+