schema-dsl 1.1.3 → 1.1.4
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 +75 -1275
- package/README.md +221 -2
- package/STATUS.md +34 -2
- package/changelogs/v1.0.0.md +328 -0
- package/changelogs/v1.0.9.md +367 -0
- package/changelogs/v1.1.0.md +389 -0
- package/changelogs/v1.1.1.md +308 -0
- package/changelogs/v1.1.2.md +183 -0
- package/changelogs/v1.1.3.md +161 -0
- package/changelogs/v1.1.4.md +432 -0
- package/docs/dsl-syntax.md +14 -3
- package/docs/optional-marker-guide.md +321 -0
- package/docs/runtime-locale-support.md +443 -0
- package/index.d.ts +126 -10
- package/index.js +6 -3
- package/index.mjs +2 -2
- package/lib/core/DslBuilder.js +11 -2
- package/lib/errors/I18nError.js +21 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,29 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## ⚡ TL;DR(30秒快速理解)
|
|
21
|
+
|
|
22
|
+
**schema-dsl 是什么?**
|
|
23
|
+
最简洁的数据验证库,一行DSL代替10行链式调用,性能超越Zod/Joi/Yup。
|
|
24
|
+
|
|
25
|
+
**核心优势:**
|
|
26
|
+
- 🎯 **极简语法**: `'string:3-32!'` 代替 8行 Joi 代码(减少 65% 代码量)
|
|
27
|
+
- 🚀 **性能第一**: 2,879,606 ops/s,比 Zod 快 1.58倍,比 Joi 快 9.61倍
|
|
28
|
+
- 🌍 **完整多语言**: 内置5种语言,支持运行时动态切换(v1.1.0+)
|
|
29
|
+
- 🎨 **独家功能**: 从验证规则直接生成 MongoDB/MySQL/PostgreSQL Schema
|
|
30
|
+
|
|
31
|
+
**3行代码上手:**
|
|
32
|
+
```javascript
|
|
33
|
+
const { dsl, validate } = require('schema-dsl');
|
|
34
|
+
const schema = dsl({ email: 'email!', age: 'number:18-' });
|
|
35
|
+
const result = validate(schema, { email: 'test@example.com', age: 25 });
|
|
36
|
+
console.log(result.valid); // true
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**5分钟教程**: [快速开始](#-快速开始) | **完整文档**: [docs/INDEX.md](./docs/INDEX.md) | **在线体验**: [RunKit](https://runkit.com/npm/schema-dsl)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
20
43
|
## 🗺️ 文档导航
|
|
21
44
|
|
|
22
45
|
**新手入门**:
|
|
@@ -45,6 +68,128 @@
|
|
|
45
68
|
|
|
46
69
|
---
|
|
47
70
|
|
|
71
|
+
## 🆕 最新特性(v1.1.0+)
|
|
72
|
+
|
|
73
|
+
### 🔗 跨类型联合验证
|
|
74
|
+
|
|
75
|
+
**一行代码支持多种类型,告别繁琐的类型判断**
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const schema = dsl({
|
|
79
|
+
contact: 'types:email|phone!', // 邮箱或手机号
|
|
80
|
+
price: 'types:number:0-|string:1-20', // 数字价格或"面议"
|
|
81
|
+
status: 'types:active|inactive|null' // 枚举或空值
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
validate(schema, { contact: 'test@example.com' }); // ✅ 通过
|
|
85
|
+
validate(schema, { contact: '13800138000' }); // ✅ 通过
|
|
86
|
+
validate(schema, { contact: 12345 }); // ❌ 失败
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**实际场景**:
|
|
90
|
+
- ✅ 用户注册:支持邮箱或手机号登录
|
|
91
|
+
- ✅ 商品价格:数字或"面议"字符串
|
|
92
|
+
- ✅ 可选字段:允许null值
|
|
93
|
+
|
|
94
|
+
📖 [完整文档](./docs/union-types.md)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### 🌍 运行时多语言支持
|
|
99
|
+
|
|
100
|
+
**无需修改全局设置,每次调用指定语言**
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
// 根据请求头动态返回不同语言的错误
|
|
104
|
+
app.post('/api/account', (req, res) => {
|
|
105
|
+
const locale = req.headers['accept-language'] || 'en-US';
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
dsl.error.assert(account, 'account.notFound', {}, 404, locale);
|
|
109
|
+
// 中文请求返回: "账户不存在"
|
|
110
|
+
// 英文请求返回: "Account not found"
|
|
111
|
+
} catch (error) {
|
|
112
|
+
res.status(error.statusCode).json(error.toJSON());
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**适用场景**:
|
|
118
|
+
- ✅ 多语言 API(根据请求头动态返回)
|
|
119
|
+
- ✅ 微服务架构(错误传递保持原语言)
|
|
120
|
+
- ✅ 国际化应用(同一请求多种语言)
|
|
121
|
+
|
|
122
|
+
📖 [运行时多语言文档](./docs/runtime-locale-support.md)
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### ⚡ 其他新特性
|
|
127
|
+
|
|
128
|
+
- ✅ **统一错误抛出**: `I18nError` 类,支持多语言错误消息
|
|
129
|
+
- ✅ **插件系统增强**: 自定义类型注册更简单
|
|
130
|
+
- ✅ **TypeScript 类型完善**: 0个类型错误(v1.1.4)
|
|
131
|
+
|
|
132
|
+
[查看完整更新日志](./CHANGELOG.md)
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 📦 功能清单(AI友好格式)
|
|
137
|
+
|
|
138
|
+
> 方便AI快速理解所有功能
|
|
139
|
+
|
|
140
|
+
### 核心功能
|
|
141
|
+
|
|
142
|
+
```json
|
|
143
|
+
{
|
|
144
|
+
"validation": {
|
|
145
|
+
"basic": ["string", "number", "boolean", "date", "email", "url", "phone", "idCard"],
|
|
146
|
+
"advanced": ["regex", "custom", "conditional", "nested", "array"],
|
|
147
|
+
"unionTypes": "v1.1.0+ 跨类型联合验证 (types:string|number)"
|
|
148
|
+
},
|
|
149
|
+
"i18n": {
|
|
150
|
+
"supported": ["zh-CN", "en-US", "ja-JP", "es-ES", "fr-FR"],
|
|
151
|
+
"features": ["配置加载", "运行时切换", "自定义消息", "参数插值"],
|
|
152
|
+
"runtime": "v1.1.0+ 运行时指定语言 (dsl.error.create(code, params, statusCode, locale))"
|
|
153
|
+
},
|
|
154
|
+
"database": {
|
|
155
|
+
"export": ["MongoDB", "MySQL", "PostgreSQL"],
|
|
156
|
+
"unique": "从验证规则直接生成数据库Schema"
|
|
157
|
+
},
|
|
158
|
+
"framework": {
|
|
159
|
+
"integration": ["Express", "Koa", "Fastify"],
|
|
160
|
+
"async": "validateAsync() 失败自动抛出 ValidationError"
|
|
161
|
+
},
|
|
162
|
+
"api": {
|
|
163
|
+
"main": ["dsl()", "validate()", "validateAsync()"],
|
|
164
|
+
"utils": ["SchemaUtils.pick()", "SchemaUtils.omit()", "SchemaUtils.partial()"],
|
|
165
|
+
"conditional": ["dsl.if()", "dsl.match()"],
|
|
166
|
+
"errors": ["ValidationError", "I18nError"]
|
|
167
|
+
},
|
|
168
|
+
"performance": {
|
|
169
|
+
"opsPerSecond": 2879606,
|
|
170
|
+
"vs": {
|
|
171
|
+
"Zod": "1.58x faster",
|
|
172
|
+
"Joi": "9.61x faster",
|
|
173
|
+
"Yup": "27.07x faster"
|
|
174
|
+
},
|
|
175
|
+
"optimization": ["WeakMap缓存", "智能编译", "批量验证优化"]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### API速查
|
|
181
|
+
|
|
182
|
+
| API | 用途 | 返回值 | 文档 |
|
|
183
|
+
|-----|------|--------|------|
|
|
184
|
+
| `dsl(schema)` | 创建Schema | Schema对象 | [DSL语法](./docs/dsl-syntax.md) |
|
|
185
|
+
| `validate(schema, data)` | 同步验证 | `{valid, errors, data}` | [验证指南](./docs/validation-guide.md) |
|
|
186
|
+
| `validateAsync(schema, data)` | 异步验证 | Promise(失败抛错) | [异步验证](./docs/validate-async.md) |
|
|
187
|
+
| `dsl.if(condition)` | 条件验证 | ConditionalBuilder | [条件API](./docs/conditional-api.md) |
|
|
188
|
+
| `SchemaUtils.pick()` | 选择字段 | 新Schema | [SchemaUtils](./docs/schema-utils.md) |
|
|
189
|
+
| `I18nError.throw()` | 抛出多语言错误 | never | [I18nError示例](./examples/i18n-error.examples.js) |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
48
193
|
## ✨ 为什么选择 schema-dsl?
|
|
49
194
|
|
|
50
195
|
### 🎯 极简 DSL 语法
|
|
@@ -137,9 +282,48 @@ validate(schema, { username: 'ab' }, { locale: 'ja-JP' });
|
|
|
137
282
|
// => "usernameは3文字以上である必要があります"
|
|
138
283
|
```
|
|
139
284
|
|
|
285
|
+
**🆕 运行时多语言支持(v1.1.0+)**
|
|
286
|
+
|
|
287
|
+
无需修改全局设置,可在每次调用时指定语言:
|
|
288
|
+
|
|
289
|
+
```javascript
|
|
290
|
+
const { dsl, I18nError } = require('schema-dsl');
|
|
291
|
+
|
|
292
|
+
// 方式1: 业务错误 - 运行时指定语言
|
|
293
|
+
const error1 = dsl.error.create('account.notFound', {}, 404, 'zh-CN');
|
|
294
|
+
console.log(error1.message); // "账户不存在"
|
|
295
|
+
|
|
296
|
+
const error2 = dsl.error.create('account.notFound', {}, 404, 'en-US');
|
|
297
|
+
console.log(error2.message); // "Account not found"
|
|
298
|
+
|
|
299
|
+
// 方式2: 断言风格 - 根据请求头动态指定
|
|
300
|
+
app.post('/api/withdraw', (req, res) => {
|
|
301
|
+
const locale = req.headers['accept-language'] || 'en-US';
|
|
302
|
+
const account = getAccount(req.user.id);
|
|
303
|
+
|
|
304
|
+
// 根据请求头返回对应语言的错误
|
|
305
|
+
I18nError.assert(account, 'account.notFound', {}, 404, locale);
|
|
306
|
+
I18nError.assert(
|
|
307
|
+
account.balance >= req.body.amount,
|
|
308
|
+
'account.insufficientBalance',
|
|
309
|
+
{ balance: account.balance, required: req.body.amount },
|
|
310
|
+
400,
|
|
311
|
+
locale
|
|
312
|
+
);
|
|
313
|
+
|
|
314
|
+
// 验证通过,继续处理...
|
|
315
|
+
});
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**适用场景**:
|
|
319
|
+
- ✅ 多语言 API(根据请求头返回不同语言)
|
|
320
|
+
- ✅ 微服务架构(错误在服务间传递时保持语言)
|
|
321
|
+
- ✅ 同一请求中需要多种语言的错误消息
|
|
322
|
+
|
|
140
323
|
**内置语言**: 中文、英文、日语、法语、西班牙语
|
|
141
324
|
|
|
142
|
-
📖 [完整多语言文档](./docs/i18n.md)
|
|
325
|
+
📖 [完整多语言文档](./docs/i18n.md)
|
|
326
|
+
📖 [运行时多语言支持](./docs/runtime-locale-support.md)
|
|
143
327
|
|
|
144
328
|
### 🎨 数据库 Schema 导出
|
|
145
329
|
|
|
@@ -1901,6 +2085,40 @@ dsl.error.throw('user.noPermission');
|
|
|
1901
2085
|
dsl.error.assert(user.role === 'admin', 'user.noPermission');
|
|
1902
2086
|
```
|
|
1903
2087
|
|
|
2088
|
+
**🆕 运行时指定语言(v1.1.0+)**
|
|
2089
|
+
|
|
2090
|
+
无需修改全局语言设置,每次调用时指定:
|
|
2091
|
+
|
|
2092
|
+
```javascript
|
|
2093
|
+
// 根据请求头动态返回不同语言
|
|
2094
|
+
app.post('/api/account', (req, res, next) => {
|
|
2095
|
+
const locale = req.headers['accept-language'] || 'en-US';
|
|
2096
|
+
const account = getAccount(req.user.id);
|
|
2097
|
+
|
|
2098
|
+
try {
|
|
2099
|
+
// 第5个参数指定语言
|
|
2100
|
+
dsl.error.assert(account, 'account.notFound', {}, 404, locale);
|
|
2101
|
+
dsl.error.assert(
|
|
2102
|
+
account.balance >= 100,
|
|
2103
|
+
'account.insufficientBalance',
|
|
2104
|
+
{ balance: account.balance, required: 100 },
|
|
2105
|
+
400,
|
|
2106
|
+
locale
|
|
2107
|
+
);
|
|
2108
|
+
// 验证通过...
|
|
2109
|
+
} catch (error) {
|
|
2110
|
+
next(error);
|
|
2111
|
+
}
|
|
2112
|
+
});
|
|
2113
|
+
|
|
2114
|
+
// 同一请求中使用不同语言
|
|
2115
|
+
const error1 = dsl.error.create('account.notFound', {}, 404, 'zh-CN');
|
|
2116
|
+
console.log(error1.message); // "账户不存在"
|
|
2117
|
+
|
|
2118
|
+
const error2 = dsl.error.create('account.notFound', {}, 404, 'en-US');
|
|
2119
|
+
console.log(error2.message); // "Account not found"
|
|
2120
|
+
```
|
|
2121
|
+
|
|
1904
2122
|
**Express/Koa 集成**:
|
|
1905
2123
|
```javascript
|
|
1906
2124
|
// 错误处理中间件
|
|
@@ -1930,7 +2148,8 @@ app.post('/withdraw', (req, res) => {
|
|
|
1930
2148
|
- 用户: `user.notFound`, `user.noPermission`
|
|
1931
2149
|
- 订单: `order.notPaid`, `order.paymentMissing`
|
|
1932
2150
|
|
|
1933
|
-
📖 完整文档请查看 [examples/i18n-error.examples.js](./examples/i18n-error.examples.js)
|
|
2151
|
+
📖 完整文档请查看 [examples/i18n-error.examples.js](./examples/i18n-error.examples.js)
|
|
2152
|
+
📖 运行时多语言支持请查看 [docs/runtime-locale-support.md](./docs/runtime-locale-support.md)
|
|
1934
2153
|
|
|
1935
2154
|
---
|
|
1936
2155
|
|
package/STATUS.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# schema-dsl 项目状态
|
|
2
2
|
|
|
3
|
-
> **最后更新**: 2026-01-
|
|
4
|
-
> **当前版本**: v1.1.
|
|
3
|
+
> **最后更新**: 2026-01-13
|
|
4
|
+
> **当前版本**: v1.1.4
|
|
5
5
|
> **项目状态**: ✅ 全部完成,测试100%通过(921个测试)
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## 📋 目录
|
|
10
10
|
|
|
11
|
+
- [v1.1.4](#v114) - 2026-01-13 ✅ 已完成
|
|
11
12
|
- [v1.1.3](#v113) - 2026-01-09 ✅ 已完成
|
|
12
13
|
- [v1.1.1](#v111) - 2026-01-06 ✅ 已完成
|
|
13
14
|
- [v1.1.0](#v110) - 2026-01-05 ✅ 已完成
|
|
@@ -26,6 +27,37 @@
|
|
|
26
27
|
|
|
27
28
|
## 版本发布计划
|
|
28
29
|
|
|
30
|
+
### v1.1.4
|
|
31
|
+
|
|
32
|
+
**发布日期**: 2026-01-13
|
|
33
|
+
**状态**: ✅ 已完成
|
|
34
|
+
**类型**: 🔧 TypeScript类型修复 + 📚 文档完善
|
|
35
|
+
**进度**: 100%完成 | 测试: 921个通过
|
|
36
|
+
|
|
37
|
+
| 需求标题 | 状态 | 优先级 | 详细 |
|
|
38
|
+
|---------|------|--------|------|
|
|
39
|
+
| 修复 dsl.error.assert 重复签名 | ✅ 完成 | P0 | index.d.ts L1336-1343 |
|
|
40
|
+
| 修复 I18nError.assert 重复签名 | ✅ 完成 | P0 | index.d.ts L1805-1821 |
|
|
41
|
+
| 完善运行时多语言文档 | ✅ 完成 | P1 | docs/runtime-locale-support.md |
|
|
42
|
+
| 更新 README.md | ✅ 完成 | P1 | 添加运行时语言支持示例 |
|
|
43
|
+
| 生成深度分析报告 | ✅ 完成 | P2 | reports/schema-dsl/analysis/ |
|
|
44
|
+
| 更新 CHANGELOG | ✅ 完成 | P0 | v1.1.4 变更记录 |
|
|
45
|
+
| 更新 STATUS | ✅ 完成 | P0 | 版本号和状态 |
|
|
46
|
+
|
|
47
|
+
**实现状态统计**:
|
|
48
|
+
- ✅ 完成: 7个
|
|
49
|
+
- 🔄 进行中: 0个
|
|
50
|
+
- ⏳ 待完成: 0个
|
|
51
|
+
|
|
52
|
+
**核心变更**:
|
|
53
|
+
- ✅ **修复**: index.d.ts 中2处重复函数签名(46个类型错误→0个错误)
|
|
54
|
+
- ✅ **文档**: 完善运行时多语言支持文档
|
|
55
|
+
- ✅ **文档**: README.md 添加运行时语言指定示例
|
|
56
|
+
- ✅ **验证**: string? 可选语法完整支持
|
|
57
|
+
- ✅ **验证**: 多语言加载机制验证
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
29
61
|
### v1.1.3
|
|
30
62
|
|
|
31
63
|
**发布日期**: 2026-01-09
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# v1.0.0 变更日志
|
|
2
|
+
|
|
3
|
+
> **发布日期**: 2025-12-29
|
|
4
|
+
> **版本号**: v1.0.0
|
|
5
|
+
> **类型**: 🎉 正式发布
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📋 变更概览
|
|
10
|
+
|
|
11
|
+
这是 schema-dsl 的首个正式发布版本,标志着项目达到生产就绪状态。
|
|
12
|
+
|
|
13
|
+
| 里程碑 | 状态 |
|
|
14
|
+
|--------|------|
|
|
15
|
+
| 核心功能完善 | ✅ |
|
|
16
|
+
| 测试覆盖充分 | ✅ |
|
|
17
|
+
| 文档完整 | ✅ |
|
|
18
|
+
| npm 发布 | ✅ |
|
|
19
|
+
| 生产就绪 | ✅ |
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🎉 核心特性
|
|
24
|
+
|
|
25
|
+
### 1. 极简 DSL 语法
|
|
26
|
+
|
|
27
|
+
**一行代码定义验证规则,代码量减少 65%**
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const { dsl } = require('schema-dsl');
|
|
31
|
+
|
|
32
|
+
// ✅ 简洁的 DSL 语法
|
|
33
|
+
const schema = dsl({
|
|
34
|
+
username: 'string:3-32!',
|
|
35
|
+
email: 'email!',
|
|
36
|
+
age: 'number:18-120',
|
|
37
|
+
tags: 'array<string>'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// ❌ 对比 Joi(需要 8 行)
|
|
41
|
+
const Joi = require('joi');
|
|
42
|
+
const joiSchema = Joi.object({
|
|
43
|
+
username: Joi.string().min(3).max(32).required(),
|
|
44
|
+
email: Joi.string().email().required(),
|
|
45
|
+
age: Joi.number().min(18).max(120),
|
|
46
|
+
tags: Joi.array().items(Joi.string())
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### 2. 完整的验证功能
|
|
53
|
+
|
|
54
|
+
#### 基础类型
|
|
55
|
+
|
|
56
|
+
- ✅ `string` - 字符串验证
|
|
57
|
+
- ✅ `number` - 数字验证
|
|
58
|
+
- ✅ `integer` - 整数验证
|
|
59
|
+
- ✅ `boolean` - 布尔值验证
|
|
60
|
+
- ✅ `date` / `datetime` - 日期时间验证
|
|
61
|
+
- ✅ `email` - 邮箱验证
|
|
62
|
+
- ✅ `url` - URL验证
|
|
63
|
+
- ✅ `phone` - 手机号验证
|
|
64
|
+
- ✅ `idCard` - 身份证验证
|
|
65
|
+
|
|
66
|
+
#### 高级功能
|
|
67
|
+
|
|
68
|
+
- ✅ **嵌套对象验证**
|
|
69
|
+
- ✅ **数组验证**
|
|
70
|
+
- ✅ **正则表达式验证**
|
|
71
|
+
- ✅ **自定义验证器**
|
|
72
|
+
- ✅ **条件验证**
|
|
73
|
+
- ✅ **枚举验证**
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### 3. 高性能设计
|
|
78
|
+
|
|
79
|
+
**性能测试结果**:
|
|
80
|
+
|
|
81
|
+
| 验证库 | 性能 (ops/s) | 相对速度 |
|
|
82
|
+
|--------|-------------|---------|
|
|
83
|
+
| **schema-dsl** | **2,879,606** | **基准 (1.00x)** |
|
|
84
|
+
| Zod | 1,818,592 | 0.63x (慢 58%) |
|
|
85
|
+
| Joi | 299,761 | 0.10x (慢 861%) |
|
|
86
|
+
| Yup | 106,378 | 0.04x (慢 2607%) |
|
|
87
|
+
|
|
88
|
+
**优化技术**:
|
|
89
|
+
- ✅ WeakMap 缓存机制
|
|
90
|
+
- ✅ 智能编译优化
|
|
91
|
+
- ✅ 批量验证优化
|
|
92
|
+
- ✅ 惰性求值
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### 4. TypeScript 完整支持
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { dsl, validate, ValidationError } from 'schema-dsl';
|
|
100
|
+
|
|
101
|
+
// 完整的类型推导
|
|
102
|
+
const schema = dsl({
|
|
103
|
+
username: 'string:3-32!',
|
|
104
|
+
email: 'email!'
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// 类型安全的验证
|
|
108
|
+
const result = validate(schema, data);
|
|
109
|
+
|
|
110
|
+
if (result.valid) {
|
|
111
|
+
console.log(result.data); // 类型推导
|
|
112
|
+
} else {
|
|
113
|
+
console.log(result.errors); // ValidationError[]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### 5. 数据库 Schema 导出
|
|
120
|
+
|
|
121
|
+
**独家功能:从验证规则直接生成数据库结构**
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
const { dsl, exporters } = require('schema-dsl');
|
|
125
|
+
|
|
126
|
+
const schema = dsl({
|
|
127
|
+
username: 'string:3-32!',
|
|
128
|
+
email: 'email!',
|
|
129
|
+
age: 'number:18-120'
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// MongoDB Schema
|
|
133
|
+
const mongoExporter = new exporters.MongoDBExporter();
|
|
134
|
+
const mongoSchema = mongoExporter.export(schema);
|
|
135
|
+
|
|
136
|
+
// MySQL DDL
|
|
137
|
+
const mysqlExporter = new exporters.MySQLExporter();
|
|
138
|
+
const mysqlDDL = mysqlExporter.export('users', schema);
|
|
139
|
+
|
|
140
|
+
// PostgreSQL DDL
|
|
141
|
+
const pgExporter = new exporters.PostgreSQLExporter();
|
|
142
|
+
const pgDDL = pgExporter.export('users', schema);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
### 6. 框架集成
|
|
148
|
+
|
|
149
|
+
**Express**
|
|
150
|
+
```javascript
|
|
151
|
+
const { validateAsync, ValidationError } = require('schema-dsl');
|
|
152
|
+
|
|
153
|
+
app.post('/api/users', async (req, res, next) => {
|
|
154
|
+
try {
|
|
155
|
+
const validData = await validateAsync(userSchema, req.body);
|
|
156
|
+
// 验证通过...
|
|
157
|
+
} catch (error) {
|
|
158
|
+
next(error);
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Koa**
|
|
164
|
+
```javascript
|
|
165
|
+
app.use(async (ctx, next) => {
|
|
166
|
+
try {
|
|
167
|
+
ctx.validData = await validateAsync(schema, ctx.request.body);
|
|
168
|
+
await next();
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if (error instanceof ValidationError) {
|
|
171
|
+
ctx.status = 400;
|
|
172
|
+
ctx.body = { errors: error.errors };
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### 7. 条件验证
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
const { dsl } = require('schema-dsl');
|
|
184
|
+
|
|
185
|
+
// 快速断言
|
|
186
|
+
dsl.if(d => d.age < 18)
|
|
187
|
+
.message('未成年用户不能注册')
|
|
188
|
+
.assert(userData);
|
|
189
|
+
|
|
190
|
+
// 复杂条件
|
|
191
|
+
dsl.if(d => d.role === 'admin')
|
|
192
|
+
.and(d => d.permissions.includes('delete'))
|
|
193
|
+
.message('权限不足')
|
|
194
|
+
.assert(user);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### 8. Schema 复用工具
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
const { SchemaUtils } = require('schema-dsl');
|
|
203
|
+
|
|
204
|
+
// 选择字段
|
|
205
|
+
const createSchema = SchemaUtils.pick(fullSchema, ['username', 'email']);
|
|
206
|
+
|
|
207
|
+
// 排除字段
|
|
208
|
+
const publicSchema = SchemaUtils.omit(fullSchema, ['password']);
|
|
209
|
+
|
|
210
|
+
// 变为可选
|
|
211
|
+
const updateSchema = SchemaUtils.partial(createSchema);
|
|
212
|
+
|
|
213
|
+
// 扩展字段
|
|
214
|
+
const registerSchema = createSchema.extend({
|
|
215
|
+
captcha: 'string:4-6!',
|
|
216
|
+
agree: 'boolean!'
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 📚 完整文档
|
|
223
|
+
|
|
224
|
+
### 用户指南
|
|
225
|
+
|
|
226
|
+
- ✅ [快速开始](../README.md#快速开始)
|
|
227
|
+
- ✅ [DSL 语法](../docs/dsl-syntax.md)
|
|
228
|
+
- ✅ [验证指南](../docs/validation-guide.md)
|
|
229
|
+
- ✅ [类型参考](../docs/type-reference.md)
|
|
230
|
+
|
|
231
|
+
### API 文档
|
|
232
|
+
|
|
233
|
+
- ✅ [dsl() API](../docs/api-reference.md)
|
|
234
|
+
- ✅ [validate() API](../docs/validate.md)
|
|
235
|
+
- ✅ [validateAsync() API](../docs/validate-async.md)
|
|
236
|
+
- ✅ [SchemaUtils API](../docs/schema-utils.md)
|
|
237
|
+
|
|
238
|
+
### 高级功能
|
|
239
|
+
|
|
240
|
+
- ✅ [条件验证](../docs/conditional-api.md)
|
|
241
|
+
- ✅ [自定义扩展](../docs/custom-extensions-guide.md)
|
|
242
|
+
- ✅ [数据库导出](../docs/mongodb-exporter.md)
|
|
243
|
+
- ✅ [性能优化](../docs/cache-manager.md)
|
|
244
|
+
|
|
245
|
+
### 框架集成
|
|
246
|
+
|
|
247
|
+
- ✅ [Express 集成](../examples/express-integration.js)
|
|
248
|
+
- ✅ [Koa 集成](../examples/middleware-usage.js)
|
|
249
|
+
- ✅ [Fastify 集成](../examples/middleware-usage.js)
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 📊 测试覆盖
|
|
254
|
+
|
|
255
|
+
- ✅ **测试套件**: 800+ 个测试用例
|
|
256
|
+
- ✅ **测试覆盖率**: 95%+
|
|
257
|
+
- ✅ **兼容性测试**: Node.js 14/16/18/20
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 🎯 生产就绪
|
|
262
|
+
|
|
263
|
+
### 质量保证
|
|
264
|
+
|
|
265
|
+
- ✅ 所有测试通过
|
|
266
|
+
- ✅ 无已知严重 Bug
|
|
267
|
+
- ✅ 文档完整
|
|
268
|
+
- ✅ API 稳定
|
|
269
|
+
|
|
270
|
+
### 性能验证
|
|
271
|
+
|
|
272
|
+
- ✅ 基准测试完成
|
|
273
|
+
- ✅ 性能优于主流验证库
|
|
274
|
+
- ✅ 内存占用合理
|
|
275
|
+
|
|
276
|
+
### 安全性
|
|
277
|
+
|
|
278
|
+
- ✅ 无已知安全漏洞
|
|
279
|
+
- ✅ 输入验证严格
|
|
280
|
+
- ✅ 错误处理完善
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## 📦 npm 发布
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
npm install schema-dsl
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**包信息**:
|
|
291
|
+
- 包名: `schema-dsl`
|
|
292
|
+
- 版本: `1.0.0`
|
|
293
|
+
- 大小: ~50KB (未压缩)
|
|
294
|
+
- 许可证: MIT
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 🎉 里程碑
|
|
299
|
+
|
|
300
|
+
v1.0.0 标志着 schema-dsl 的以下成就:
|
|
301
|
+
|
|
302
|
+
1. ✅ **功能完整**: 覆盖所有常见验证场景
|
|
303
|
+
2. ✅ **性能优秀**: 超越主流验证库
|
|
304
|
+
3. ✅ **文档完善**: 40+ 篇详细文档
|
|
305
|
+
4. ✅ **测试充分**: 800+ 测试用例
|
|
306
|
+
5. ✅ **生产就绪**: 可用于生产环境
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
## 🙏 致谢
|
|
311
|
+
|
|
312
|
+
感谢所有测试用户和贡献者的反馈,让 schema-dsl 达到了生产就绪的质量标准。
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 🔗 相关链接
|
|
317
|
+
|
|
318
|
+
- [GitHub Repository](https://github.com/vextjs/schema-dsl)
|
|
319
|
+
- [npm Package](https://www.npmjs.com/package/schema-dsl)
|
|
320
|
+
- [完整文档](../docs/INDEX.md)
|
|
321
|
+
- [在线体验](https://runkit.com/npm/schema-dsl)
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
**发布者**: schema-dsl Team
|
|
326
|
+
**发布时间**: 2025-12-29
|
|
327
|
+
**下一版本**: v1.0.1
|
|
328
|
+
|