schema-dsl 1.0.3 → 1.0.5

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.
package/CHANGELOG.md CHANGED
@@ -11,6 +11,7 @@
11
11
 
12
12
  | 版本 | 日期 | 变更摘要 | 详细 |
13
13
  |------|------|---------|------|
14
+ | [v1.0.4](#v104) | 2025-12-31 | TypeScript 完整支持、validateAsync、ValidationError | [查看详情](#v104) |
14
15
  | [v1.0.3](#v103) | 2025-12-31 | ⚠️ 破坏性变更:单值语法修复 | [查看详情](#v103) |
15
16
  | [v1.0.2](#v102) | 2025-12-31 | 15个新增验证器、完整文档、75个测试 | [查看详情](#v102) |
16
17
  | [v1.0.1](#v101) | 2025-12-31 | 枚举功能、自动类型识别、统一错误消息 | [查看详情](#v101) |
@@ -18,6 +19,63 @@
18
19
 
19
20
  ---
20
21
 
22
+ ## [v1.0.4] - 2025-12-31
23
+
24
+ ### Added (新增功能)
25
+
26
+ #### TypeScript 完整支持 ⭐
27
+
28
+ - ✅ **完整的类型定义**
29
+ - 新增 `validateAsync` 函数类型定义
30
+ - 新增 `ValidationError` 类完整类型(包含所有方法)
31
+ - 优化 String 扩展的 TypeScript 说明
32
+
33
+ - ✅ **TypeScript 使用指南**
34
+ - 创建完整的 TypeScript 使用文档 (`docs/typescript-guide.md`)
35
+ - 1000+ 行详细说明,涵盖从基础到高级所有场景
36
+ - 3个完整实战案例(用户注册、API验证、字段复用)
37
+ - 5个常见问题解答
38
+
39
+ - ✅ **TypeScript 链式调用最佳实践**
40
+ ```typescript
41
+ // ✅ 推荐:使用 dsl() 包裹获得完整类型推导
42
+ const schema = dsl({
43
+ email: dsl('email!').label('邮箱').pattern(/custom/)
44
+ });
45
+
46
+ // ❌ 不推荐:可能缺少类型提示
47
+ const schema = dsl({
48
+ email: 'email!'.label('邮箱')
49
+ });
50
+ ```
51
+
52
+ ### Improved (改进)
53
+
54
+ - 📝 **README 更新**
55
+ - 添加 "1.5 TypeScript 用法" 快速开始章节
56
+ - 添加 TypeScript 使用指南链接
57
+ - 清晰说明 TypeScript 和 JavaScript 的不同用法
58
+
59
+ - 🔧 **类型定义优化**
60
+ - 修复 `dsl.config` 的 `i18n` 参数类型错误
61
+ - 统一 `DslConfigOptions` 和 `dsl.config` 的类型定义
62
+ - 标记 String 扩展方法为 `@deprecated` for TypeScript
63
+
64
+ ### Documentation (文档)
65
+
66
+ - 📚 新增文档
67
+ - `docs/typescript-guide.md` - TypeScript 使用指南(1000+ 行)
68
+ - `reports/schema-dsl/implementation/dollar-method-implementation-v1.0.4.md` - 实施报告
69
+ - `reports/schema-dsl/summary/typescript-support-completion-v1.0.4.md` - 完成总结
70
+
71
+ ### Note (重要说明)
72
+
73
+ - ✅ **100% 向后兼容** - JavaScript 用户无需任何改变
74
+ - ✅ **TypeScript 用户推荐使用 `dsl()` 包裹字符串** 以获得完整类型推导
75
+ - ✅ **所有 API 都有完整的 TypeScript 类型定义**
76
+
77
+ ---
78
+
21
79
  ## [v1.0.3] - 2025-12-31
22
80
 
23
81
  ### ⚠️ 破坏性变更 (Breaking Changes)
package/README.md CHANGED
@@ -96,6 +96,8 @@ validate(schema, data, { locale: 'en-US' });
96
96
  **一份定义,多处使用**
97
97
 
98
98
  ```javascript
99
+ const { dsl, exporters } = require('schema-dsl');
100
+
99
101
  const schema = dsl({
100
102
  username: 'string:3-32!',
101
103
  email: 'email!',
@@ -103,13 +105,16 @@ const schema = dsl({
103
105
  });
104
106
 
105
107
  // 导出 MongoDB Schema
106
- schema.exportTo('mongodb', { collectionName: 'users' });
108
+ const mongoExporter = new exporters.MongoDBExporter();
109
+ const mongoSchema = mongoExporter.export(schema);
107
110
 
108
111
  // 导出 MySQL 建表语句
109
- schema.exportTo('mysql', { tableName: 'users' });
112
+ const mysqlExporter = new exporters.MySQLExporter();
113
+ const mysqlDDL = mysqlExporter.export('users', schema);
110
114
 
111
115
  // 导出 PostgreSQL 建表语句
112
- schema.exportTo('postgresql', { tableName: 'users' });
116
+ const pgExporter = new exporters.PostgreSQLExporter();
117
+ const pgDDL = pgExporter.export('users', schema);
113
118
  ```
114
119
 
115
120
  **✅ 独家功能**:从验证规则直接生成数据库结构!
@@ -172,10 +177,13 @@ npm install schema-dsl
172
177
 
173
178
  ## 🚀 快速开始
174
179
 
175
- ### 1. 基础验证
180
+ ### 1. 基础验证(JavaScript)
176
181
 
177
182
  ```javascript
178
183
  const { dsl, validate } = require('schema-dsl');
184
+
185
+ const userSchema = dsl({
186
+ username: 'string:3-32!',
179
187
  email: 'email!',
180
188
  age: 'number:18-120',
181
189
  tags: 'array<string>'
@@ -210,7 +218,52 @@ console.log(result2.errors); // 错误列表
210
218
  */
211
219
  ```
212
220
 
213
- ### Express 集成 - 自动错误处理
221
+ ### 1.5 TypeScript 用法
222
+
223
+ **重要**: TypeScript 中使用链式调用需要用 `dsl()` 包裹字符串以获得完整的类型推导:
224
+
225
+ ```typescript
226
+ import { dsl, validateAsync, ValidationError } from 'schema-dsl';
227
+
228
+ // ✅ 推荐:使用 dsl() 包裹字符串获得完整类型提示
229
+ const userSchema = dsl({
230
+ username: dsl('string:3-32!')
231
+ .pattern(/^[a-zA-Z0-9_]+$/, '只能包含字母、数字和下划线')
232
+ .label('用户名'),
233
+
234
+ email: dsl('email!')
235
+ .label('邮箱地址')
236
+ .messages({ required: '邮箱必填' }),
237
+
238
+ age: dsl('number:18-100')
239
+ .label('年龄')
240
+ });
241
+
242
+ // 异步验证(推荐)
243
+ try {
244
+ const validData = await validateAsync(userSchema, {
245
+ username: 'testuser',
246
+ email: 'test@example.com',
247
+ age: 25
248
+ });
249
+ console.log('验证通过:', validData);
250
+ } catch (error) {
251
+ if (error instanceof ValidationError) {
252
+ error.errors.forEach(err => {
253
+ console.log(`${err.path}: ${err.message}`);
254
+ });
255
+ }
256
+ }
257
+ ```
258
+
259
+ **为什么要用 `dsl()` 包裹?**
260
+ - ✅ 完整的类型推导和 IDE 自动提示
261
+ - ✅ 避免 TypeScript 严格模式警告
262
+ - ✅ 更好的开发体验
263
+
264
+ **详细说明**: 请查看 [TypeScript 使用指南](./docs/typescript-guide.md)
265
+
266
+ ### 2. Express 集成 - 自动错误处理
214
267
 
215
268
  ```javascript
216
269
  const { dsl, validateAsync, ValidationError } = require('schema-dsl');
@@ -477,17 +530,82 @@ dsl({
477
530
  email: 'email!'.label('用户邮箱'),
478
531
 
479
532
  // 字段描述
480
- bio: 'string:10-500'.description('用户简介,10-500字符'),
533
+ bio: 'string:10-500'.description('用户简介,10-500字符')
534
+ })
535
+ ```
536
+
537
+ ### 条件验证 - dsl.match 和 dsl.if
538
+
539
+ **根据其他字段的值动态决定验证规则**
540
+
541
+ ```javascript
542
+ const { dsl } = require('schema-dsl');
543
+
544
+ // 1. dsl.match - 根据字段值匹配不同规则(类似 switch-case)
545
+ const contactSchema = dsl({
546
+ contactType: 'email|phone|wechat',
481
547
 
482
- // 条件验证
483
- discount: 'number'.when('vip', {
484
- is: true,
485
- then: 'number:10-50!', // VIP 用户折扣必填
486
- otherwise: 'number' // 普通用户可选
548
+ // 根据 contactType 的值决定 contact 字段的验证规则
549
+ contact: dsl.match('contactType', {
550
+ email: 'email!', // contactType='email' 时验证邮箱格式
551
+ phone: 'string:11!', // contactType='phone' 时验证11位手机号
552
+ wechat: 'string:6-20!', // contactType='wechat' 时验证微信号
553
+ _default: 'string' // 默认规则(可选)
487
554
  })
488
- })
555
+ });
556
+
557
+ // ✅ 验证通过
558
+ validate(contactSchema, { contactType: 'email', contact: 'user@example.com' });
559
+ validate(contactSchema, { contactType: 'phone', contact: '13800138000' });
560
+
561
+ // ❌ 验证失败
562
+ validate(contactSchema, { contactType: 'email', contact: 'invalid' });
563
+
564
+
565
+ // 2. dsl.if - 简单条件分支(类似 if-else)
566
+ const vipSchema = dsl({
567
+ isVip: 'boolean!',
568
+
569
+ // 如果是 VIP,折扣必须在 10-50 之间;否则在 0-10 之间
570
+ discount: dsl.if('isVip', 'number:10-50!', 'number:0-10')
571
+ });
572
+
573
+ // ✅ VIP 用户
574
+ validate(vipSchema, { isVip: true, discount: 30 });
575
+
576
+ // ❌ 非 VIP 用户折扣超过 10
577
+ validate(vipSchema, { isVip: false, discount: 15 });
578
+
579
+
580
+ // 3. 实际应用场景:订单验证
581
+ const orderSchema = dsl({
582
+ paymentMethod: 'alipay|wechat|card|cod', // cod = 货到付款
583
+
584
+ // 根据支付方式决定支付信息格式
585
+ paymentInfo: dsl.match('paymentMethod', {
586
+ alipay: 'email!', // 支付宝:邮箱
587
+ wechat: 'string:20-30', // 微信:支付串
588
+ card: 'string:16-19', // 银行卡:卡号
589
+ cod: 'string:0-0', // 货到付款:无需支付信息
590
+ _default: 'string'
591
+ }),
592
+
593
+ // 货到付款需要详细地址
594
+ address: dsl.if('paymentMethod',
595
+ 'string:10-200!', // cod = 货到付款时地址必填
596
+ 'string:10-200' // 其他支付方式地址可选
597
+ )
598
+ });
489
599
  ```
490
600
 
601
+ **💡 使用场景**:
602
+ - ✅ 多种联系方式验证(邮箱/手机/微信)
603
+ - ✅ VIP 和普通用户不同的折扣范围
604
+ - ✅ 不同支付方式的支付信息格式
605
+ - ✅ 根据用户类型决定必填字段
606
+
607
+ **查看完整示例**: [examples/dsl-match-example.js](./examples/dsl-match-example.js)
608
+
491
609
  ---
492
610
 
493
611
  ## 🔧 核心功能
@@ -605,32 +723,36 @@ const markdown = exporters.MarkdownExporter.export(userSchema, {
605
723
  ### 4. 多语言支持
606
724
 
607
725
  ```javascript
608
- const { dsl, Locale } = require('schema-dsl');
726
+ const { dsl, validate } = require('schema-dsl');
727
+ const path = require('path');
728
+
729
+ // 方式 1: 从目录加载语言包(推荐)
730
+ dsl.config({
731
+ i18n: path.join(__dirname, 'i18n/dsl') // 直接传字符串路径
732
+ });
609
733
 
610
- // 配置语言包
734
+ // 方式 2: 直接传入语言包对象
611
735
  dsl.config({
612
736
  i18n: {
613
- locales: {
614
- 'zh-CN': {
615
- 'label.username': '用户名',
616
- 'label.email': '邮箱地址',
617
- 'required': '{{#label}}不能为空',
618
- 'string.min': '{{#label}}长度不能少于{{#limit}}个字符'
619
- },
620
- 'en-US': {
621
- 'label.username': 'Username',
622
- 'label.email': 'Email Address',
623
- 'required': '{{#label}} is required',
624
- 'string.min': '{{#label}} must be at least {{#limit}} characters'
625
- }
737
+ 'zh-CN': {
738
+ 'label.username': '用户名',
739
+ 'label.email': '邮箱地址',
740
+ 'required': '{{#label}}不能为空',
741
+ 'string.min': '{{#label}}长度不能少于{{#limit}}个字符'
742
+ },
743
+ 'en-US': {
744
+ 'label.username': 'Username',
745
+ 'label.email': 'Email Address',
746
+ 'required': '{{#label}} is required',
747
+ 'string.min': '{{#label}} must be at least {{#limit}} characters'
626
748
  }
627
749
  }
628
750
  });
629
751
 
630
752
  // 使用 Label Key
631
753
  const schema = dsl({
632
- username: 'string:3-32!'.label('label.username'),
633
- email: 'email!'.label('label.email')
754
+ username: dsl('string:3-32!').label('label.username'),
755
+ email: dsl('email!').label('label.email')
634
756
  });
635
757
 
636
758
  // 验证时指定语言
@@ -639,16 +761,44 @@ const result1 = validate(schema, data, { locale: 'zh-CN' });
639
761
 
640
762
  const result2 = validate(schema, data, { locale: 'en-US' });
641
763
  // 错误消息:Username must be at least 3 characters
764
+ ```
642
765
 
643
- // 从文件加载语言包
644
- dsl.config({
645
- i18n: {
646
- localesPath: './i18n' // 自动加载 ./i18n/*.js *.json
766
+ ### 5. 缓存配置 (v1.0.4+)
767
+
768
+ ```javascript
769
+ const { dsl, config } = require('schema-dsl');
770
+
771
+ // 配置缓存选项(推荐在使用 DSL 之前调用)
772
+ config({
773
+ cache: {
774
+ maxSize: 1000, // 最大缓存条目数(默认:100)
775
+ ttl: 7200000, // 缓存过期时间(毫秒,默认:3600000,即1小时)
776
+ enabled: true, // 是否启用缓存(默认:true)
777
+ statsEnabled: true // 是否启用统计(默认:true)
647
778
  }
648
779
  });
780
+
781
+ // 之后创建的 Schema 将使用新的缓存配置
782
+ const schema = dsl({ name: 'string!' });
783
+
784
+ // 也可以在 Validator 创建后动态修改配置(向后兼容)
785
+ const { getDefaultValidator } = require('schema-dsl');
786
+ const validator = getDefaultValidator();
787
+ console.log('当前缓存配置:', validator.cache.options);
788
+
789
+ // 动态修改
790
+ config({
791
+ cache: { maxSize: 5000 } // 只修改某个参数
792
+ });
649
793
  ```
650
794
 
651
- ### 5. 插件系统
795
+ **缓存说明**:
796
+ - Schema 编译结果会被缓存以提高性能
797
+ - 使用 LRU(最近最少使用)淘汰策略
798
+ - 支持 TTL(生存时间)自动过期
799
+ - 可通过 `validator.cache.getStats()` 查看缓存统计信息
800
+
801
+ ### 6. 插件系统
652
802
 
653
803
  ```javascript
654
804
  const { PluginManager } = require('schema-dsl');
@@ -700,7 +850,7 @@ const schema = dsl({
700
850
  });
701
851
  ```
702
852
 
703
- ### 6. 错误处理
853
+ ### 7. 错误处理
704
854
 
705
855
  ```javascript
706
856
  const { validate, ValidationError } = require('schema-dsl');
@@ -937,6 +1087,7 @@ const dynamicSchema = dsl(
937
1087
  - [快速开始](./docs/quick-start.md) - 5分钟上手指南
938
1088
  - [DSL 语法完整参考](./docs/dsl-syntax.md) - 所有语法详解
939
1089
  - [API 文档](./docs/api-reference.md) - 完整 API 说明
1090
+ - [**TypeScript 使用指南**](./docs/typescript-guide.md) - TypeScript 最佳实践 ⭐
940
1091
 
941
1092
  ### 功能指南
942
1093
  - [String 扩展方法](./docs/string-extensions.md) - 链式调用详解
package/STATUS.md CHANGED
@@ -1,13 +1,14 @@
1
1
  # schema-dsl 项目状态
2
2
 
3
3
  > **最后更新**: 2025-12-31
4
- > **当前版本**: v1.0.3
4
+ > **当前版本**: v1.0.4
5
5
  > **项目状态**: ✅ 全部完成,测试100%通过
6
6
 
7
7
  ---
8
8
 
9
9
  ## 📋 目录
10
10
 
11
+ - [v1.0.4](#v104) - 2025-12-31 ✅ 已完成
11
12
  - [v1.0.3](#v103) - 2025-12-31 ⚠️ 破坏性变更
12
13
  - [v1.0.2](#v102) - 2025-12-31 ✅ 已完成
13
14
  - [v1.0.1](#v101) - 2025-12-31 ✅ 已完成
@@ -17,6 +18,43 @@
17
18
 
18
19
  ## 版本发布计划
19
20
 
21
+ ### v1.0.4
22
+
23
+ **发布日期**: 2025-12-31
24
+ **状态**: ✅ 已完成
25
+ **类型**: ✨ 功能增强(TypeScript 完整支持)
26
+ **进度**: 100%完成 | 新增: TypeScript 类型定义、使用指南 | 文档: 1500+ 行
27
+
28
+ | 需求标题 | 状态 | 优先级 | 详细 |
29
+ |---------|------|--------|------|
30
+ | 完善 index.d.ts | ✅ 完成 | P0 | validateAsync、ValidationError 类型 |
31
+ | String 扩展 TS 说明 | ✅ 完成 | P0 | 添加详细使用说明和对比 |
32
+ | TypeScript 使用指南 | ✅ 完成 | P0 | 1000+ 行完整文档 |
33
+ | README 更新 | ✅ 完成 | P0 | 添加 TypeScript 章节 |
34
+ | 类型错误修复 | ✅ 完成 | P0 | 修复 dsl.config i18n 类型 |
35
+ | 发版文档更新 | ✅ 完成 | P0 | CHANGELOG、STATUS、package.json |
36
+
37
+ **实现状态统计**:
38
+ - ✅ 完成: 6个
39
+ - 🔄 进行中: 0个
40
+ - ⏳ 待完成: 0个
41
+
42
+ **核心变更**:
43
+ - ✅ **新增**: validateAsync 函数完整类型定义
44
+ - ✅ **新增**: ValidationError 类完整类型(含所有方法)
45
+ - ✅ **优化**: String 扩展添加 TypeScript 使用说明
46
+ - ✅ **新增**: TypeScript 使用指南文档(1000+ 行)
47
+ - ✅ **修复**: dsl.config 的 i18n 参数类型错误
48
+ - ✅ **文档**: README 添加 TypeScript 快速开始章节
49
+
50
+ **用户价值**:
51
+ - 🎯 TypeScript 用户获得完整的类型安全和 IDE 提示
52
+ - 🎯 详细的文档指导如何在 TypeScript 中正确使用
53
+ - 🎯 JavaScript 用户体验不变,100% 向后兼容
54
+ - 🎯 降低学习成本,提高开发效率
55
+
56
+ ---
57
+
20
58
  ### v1.0.3
21
59
 
22
60
  **发布日期**: 2025-12-31
package/docs/i18n.md CHANGED
@@ -19,12 +19,12 @@ schema-dsl 支持完整的多语言功能,允许你自定义字段标签和错
19
19
  const { dsl, validate } = require('schema-dsl');
20
20
  const path = require('path');
21
21
 
22
- // 方式 1: 从目录加载(推荐)
22
+ // 方式 1: 从目录加载(推荐)
23
23
  dsl.config({
24
- i18n: path.join(__dirname, 'i18n/dsl')
24
+ i18n: path.join(__dirname, 'i18n/dsl') // 直接传字符串路径
25
25
  });
26
26
 
27
- // 方式 2: 直接传入对象
27
+ // 方式 2: 直接传入对象
28
28
  dsl.config({
29
29
  i18n: {
30
30
  'zh-CN': require('./i18n/dsl/zh-CN'),
@@ -3,7 +3,7 @@
3
3
  ## 📋 测试概述
4
4
 
5
5
  **测试日期**: 2024-01-XX
6
- **测试版本**: v1.0.3
6
+ **测试版本**: v1.0.4
7
7
  **测试环境**: Node.js (运行环境)
8
8
  **对比库**: Joi, Yup, Zod, Ajv
9
9