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.
- package/CHANGELOG.md +325 -2
- package/README.md +419 -189
- package/STATUS.md +65 -3
- package/docs/FEATURE-INDEX.md +1 -1
- package/docs/best-practices.md +3 -3
- package/docs/cache-manager.md +1 -1
- package/docs/conditional-api.md +1278 -0
- package/docs/dsl-syntax.md +1 -1
- package/docs/dynamic-locale.md +2 -2
- package/docs/error-handling.md +2 -2
- package/docs/export-guide.md +2 -2
- package/docs/export-limitations.md +3 -3
- package/docs/faq.md +6 -6
- package/docs/frontend-i18n-guide.md +1 -1
- package/docs/mongodb-exporter.md +3 -3
- package/docs/multi-type-support.md +12 -2
- package/docs/mysql-exporter.md +1 -1
- package/docs/plugin-system.md +4 -4
- package/docs/postgresql-exporter.md +1 -1
- package/docs/quick-start.md +4 -4
- package/docs/troubleshooting.md +2 -2
- package/docs/type-reference.md +5 -5
- package/docs/typescript-guide.md +5 -6
- package/docs/union-type-guide.md +147 -0
- package/docs/union-types.md +277 -0
- package/docs/validate-async.md +1 -1
- package/examples/array-dsl-example.js +1 -1
- package/examples/conditional-example.js +288 -0
- package/examples/conditional-non-object.js +129 -0
- package/examples/conditional-validate-example.js +321 -0
- package/examples/i18n-error.examples.js +181 -0
- package/examples/union-type-example.js +127 -0
- package/examples/union-types-example.js +77 -0
- package/index.d.ts +655 -7
- package/index.js +54 -3
- package/lib/adapters/DslAdapter.js +14 -5
- package/lib/core/ConditionalBuilder.js +503 -0
- package/lib/core/DslBuilder.js +113 -0
- package/lib/core/Locale.js +13 -8
- package/lib/core/Validator.js +250 -2
- package/lib/errors/I18nError.js +222 -0
- package/lib/locales/en-US.js +39 -0
- package/lib/locales/es-ES.js +4 -0
- package/lib/locales/fr-FR.js +4 -0
- package/lib/locales/ja-JP.js +9 -0
- package/lib/locales/zh-CN.js +39 -0
- package/package.json +3 -1
package/docs/dsl-syntax.md
CHANGED
package/docs/dynamic-locale.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
## 基本原理
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
SchemaI-DSL 的 `Validator` 支持在验证时动态指定语言,无需全局切换。
|
|
22
22
|
|
|
23
23
|
### 核心方法
|
|
24
24
|
|
|
@@ -593,6 +593,6 @@ const schema = dsl({
|
|
|
593
593
|
---
|
|
594
594
|
|
|
595
595
|
**最后更新**: 2025-12-25
|
|
596
|
-
**作者**:
|
|
596
|
+
**作者**: SchemaI-DSL Team
|
|
597
597
|
|
|
598
598
|
|
package/docs/error-handling.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
### 基础结构
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
SchemaI-DSL 验证返回的错误对象结构:
|
|
27
27
|
|
|
28
28
|
```javascript
|
|
29
29
|
const { dsl, validate } = require('schema-dsl');
|
|
@@ -165,7 +165,7 @@ Locale.setMessages({
|
|
|
165
165
|
|
|
166
166
|
### 内置错误码(简化版)
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
SchemaI-DSL 对 ajv 的错误关键字进行了简化映射,使其更易用:
|
|
169
169
|
|
|
170
170
|
#### 字符串错误码
|
|
171
171
|
|
package/docs/export-guide.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> **用途**: Schema 到数据库 DDL 的完整导出指南
|
|
4
4
|
> **阅读时间**: 10分钟
|
|
5
5
|
|
|
6
|
-
> ⚠️ **重要提示**: 并非所有
|
|
6
|
+
> ⚠️ **重要提示**: 并非所有 SchemaI-DSL 特性都能导出到数据库。请先阅读 [导出限制说明](export-limitations.md) 了解哪些特性不支持导出。
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
## 概述
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
SchemaI-DSL 支持将 JSON Schema 导出为多种数据库的 DDL 语句,实现"一次定义,多处使用"。
|
|
25
25
|
|
|
26
26
|
### 支持的数据库
|
|
27
27
|
|
|
@@ -49,7 +49,7 @@ const schema = dsl({
|
|
|
49
49
|
|
|
50
50
|
**替代方案**:
|
|
51
51
|
- 导出为最宽松的类型(`VARCHAR(255)`)
|
|
52
|
-
- 验证逻辑保留在应用层(使用
|
|
52
|
+
- 验证逻辑保留在应用层(使用 SchemaI-DSL 验证器)
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
@@ -331,7 +331,7 @@ const schema = dsl('string!')
|
|
|
331
331
|
|
|
332
332
|
```
|
|
333
333
|
┌─────────────────────────────────────────┐
|
|
334
|
-
│ 应用层(
|
|
334
|
+
│ 应用层(SchemaI-DSL 完整验证) │
|
|
335
335
|
│ - 条件逻辑(match/if) │
|
|
336
336
|
│ - 自定义验证器 │
|
|
337
337
|
│ - 复杂约束(正则、范围等) │
|
|
@@ -449,7 +449,7 @@ module.exports = {
|
|
|
449
449
|
```markdown
|
|
450
450
|
## 数据验证说明
|
|
451
451
|
|
|
452
|
-
### 应用层验证(
|
|
452
|
+
### 应用层验证(SchemaI-DSL)
|
|
453
453
|
- ✅ `contact` 字段根据 `contactType` 动态验证
|
|
454
454
|
- ✅ 用户名正则验证(`^[a-zA-Z0-9_]+$`)
|
|
455
455
|
- ✅ 自定义业务规则验证
|
package/docs/faq.md
CHANGED
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
|
|
21
21
|
## 基础问题
|
|
22
22
|
|
|
23
|
-
### Q:
|
|
23
|
+
### Q: SchemaI-DSL 和 Joi、Yup 有什么区别?
|
|
24
24
|
|
|
25
|
-
**A**:
|
|
25
|
+
**A**: SchemaI-DSL 采用 DSL 语法,更简洁:
|
|
26
26
|
|
|
27
27
|
```javascript
|
|
28
|
-
//
|
|
28
|
+
// SchemaI-DSL - 简洁
|
|
29
29
|
const schema = dsl({
|
|
30
30
|
username: 'string:3-32!',
|
|
31
31
|
email: 'email!'
|
|
@@ -46,7 +46,7 @@ const schema = Joi.object({
|
|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
49
|
-
### Q: 如何安装
|
|
49
|
+
### Q: 如何安装 SchemaI-DSL?
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
52
|
npm install schema-dsl
|
|
@@ -299,7 +299,7 @@ app.post('/api/users', (req, res) => {
|
|
|
299
299
|
|
|
300
300
|
### Q: 缓存如何工作?
|
|
301
301
|
|
|
302
|
-
**A**:
|
|
302
|
+
**A**: SchemaI-DSL 内置 LRU 缓存:
|
|
303
303
|
|
|
304
304
|
```javascript
|
|
305
305
|
const validator = new Validator({
|
|
@@ -523,7 +523,7 @@ MySQL 会生成 `COMMENT`,PostgreSQL 会生成 `COMMENT ON COLUMN`。
|
|
|
523
523
|
|
|
524
524
|
## TypeScript 支持
|
|
525
525
|
|
|
526
|
-
### Q:
|
|
526
|
+
### Q: SchemaI-DSL 支持 TypeScript 吗?
|
|
527
527
|
|
|
528
528
|
**A**: 支持,类型定义在 `index.d.ts`:
|
|
529
529
|
|
|
@@ -250,7 +250,7 @@ Locale.addLocale('de-DE', {
|
|
|
250
250
|
**A**: 后端返回错误消息已经是本地化的,前端无需处理。如果需要前端验证:
|
|
251
251
|
|
|
252
252
|
```javascript
|
|
253
|
-
// 前端可以使用相同的
|
|
253
|
+
// 前端可以使用相同的 SchemaI-DSL(浏览器版)
|
|
254
254
|
import { dsl, validate } from 'schema-dsl/browser';
|
|
255
255
|
|
|
256
256
|
const schema = dsl({ /* ... */ });
|
package/docs/mongodb-exporter.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
|
|
20
20
|
## 概述
|
|
21
21
|
|
|
22
|
-
`MongoDBExporter` 将
|
|
22
|
+
`MongoDBExporter` 将 SchemaI-DSL 生成的 JSON Schema 转换为 MongoDB 的 `$jsonSchema` 验证格式,可直接用于创建集合时的文档验证。
|
|
23
23
|
|
|
24
24
|
### 核心功能
|
|
25
25
|
|
|
@@ -104,7 +104,7 @@ const mongoSchema = exporter.export(jsonSchema);
|
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
**参数**:
|
|
107
|
-
- `jsonSchema` (Object):
|
|
107
|
+
- `jsonSchema` (Object): SchemaI-DSL 生成的 JSON Schema 对象
|
|
108
108
|
|
|
109
109
|
**返回值**:
|
|
110
110
|
- `Object`: 包含 `$jsonSchema` 的 MongoDB 验证对象
|
|
@@ -272,7 +272,7 @@ async function createValidatedCollection() {
|
|
|
272
272
|
|
|
273
273
|
## 导出限制
|
|
274
274
|
|
|
275
|
-
⚠️ **重要提示**: 并非所有
|
|
275
|
+
⚠️ **重要提示**: 并非所有 SchemaI-DSL 特性都能导出到数据库 Schema。
|
|
276
276
|
|
|
277
277
|
**不支持导出的特性**:
|
|
278
278
|
- ❌ 条件验证逻辑(`dsl.match()`, `dsl.if()`)
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
# 多类型支持设计说明
|
|
2
2
|
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## 📖 快速导航
|
|
6
|
+
|
|
7
|
+
- **单一类型验证**(本文档)
|
|
8
|
+
- **[联合类型验证](./union-type-guide.md)** - 一个字段支持多种类型(使用 `.pattern()` 正则匹配)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
3
12
|
## 🎯 设计原理
|
|
4
13
|
|
|
5
|
-
|
|
14
|
+
schema-dsl通过**类型无关的Builder模式**实现多类型支持。
|
|
6
15
|
|
|
7
16
|
### 核心设计
|
|
8
17
|
|
|
@@ -21,6 +30,7 @@ class DslBuilder {
|
|
|
21
30
|
|
|
22
31
|
---
|
|
23
32
|
|
|
33
|
+
|
|
24
34
|
## 📊 类型支持矩阵
|
|
25
35
|
|
|
26
36
|
| DSL字符串 | 解析类型 | 支持的方法 |
|
|
@@ -307,7 +317,7 @@ amount: 'number:0-10000'
|
|
|
307
317
|
|
|
308
318
|
## 💡 总结
|
|
309
319
|
|
|
310
|
-
|
|
320
|
+
SchemaI-DSL的多类型支持采用**类型无关Builder + 方法智能适配**设计:
|
|
311
321
|
|
|
312
322
|
1. **统一入口**: 所有类型都通过DslBuilder
|
|
313
323
|
2. **类型感知**: 方法内部检查类型兼容性
|
package/docs/mysql-exporter.md
CHANGED
package/docs/plugin-system.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
## 概述
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
SchemaI-DSL 插件系统允许你扩展核心功能,添加自定义验证器、格式化器、导出器等。
|
|
24
24
|
|
|
25
25
|
### 特性
|
|
26
26
|
|
|
@@ -342,7 +342,7 @@ pluginManager.register({
|
|
|
342
342
|
安装插件。
|
|
343
343
|
|
|
344
344
|
**参数**:
|
|
345
|
-
- `schema-dsl` (Object) -
|
|
345
|
+
- `schema-dsl` (Object) - SchemaI-DSL 实例
|
|
346
346
|
- `pluginName` (String, optional) - 插件名称
|
|
347
347
|
- `options` (Object, optional) - 安装选项
|
|
348
348
|
|
|
@@ -354,7 +354,7 @@ pluginManager.register({
|
|
|
354
354
|
|
|
355
355
|
**参数**:
|
|
356
356
|
- `pluginName` (String) - 插件名称
|
|
357
|
-
- `schema-dsl` (Object) -
|
|
357
|
+
- `schema-dsl` (Object) - SchemaI-DSL 实例
|
|
358
358
|
|
|
359
359
|
**返回**: `this`
|
|
360
360
|
|
|
@@ -398,7 +398,7 @@ pluginManager.register({
|
|
|
398
398
|
清空所有插件。
|
|
399
399
|
|
|
400
400
|
**参数**:
|
|
401
|
-
- `schema-dsl` (Object) -
|
|
401
|
+
- `schema-dsl` (Object) - SchemaI-DSL 实例
|
|
402
402
|
|
|
403
403
|
**返回**: `this`
|
|
404
404
|
|
package/docs/quick-start.md
CHANGED
|
@@ -413,13 +413,13 @@ uninstallStringExtensions();
|
|
|
413
413
|
|
|
414
414
|
### Q: 支持TypeScript吗?
|
|
415
415
|
|
|
416
|
-
**A**: 支持!
|
|
416
|
+
**A**: 支持!SchemaI-DSL提供完整的TypeScript类型定义。
|
|
417
417
|
|
|
418
418
|
---
|
|
419
419
|
|
|
420
420
|
## 🎉 恭喜!
|
|
421
421
|
|
|
422
|
-
你已经掌握了
|
|
422
|
+
你已经掌握了SchemaI-DSL的核心用法!
|
|
423
423
|
|
|
424
424
|
**核心要点**:
|
|
425
425
|
1. ✅ DSL语法简洁直观
|
|
@@ -737,13 +737,13 @@ uninstallStringExtensions();
|
|
|
737
737
|
|
|
738
738
|
### Q: 支持TypeScript吗?
|
|
739
739
|
|
|
740
|
-
**A**: 支持!
|
|
740
|
+
**A**: 支持!SchemaI-DSL提供完整的TypeScript类型定义。
|
|
741
741
|
|
|
742
742
|
---
|
|
743
743
|
|
|
744
744
|
## 🎉 恭喜!
|
|
745
745
|
|
|
746
|
-
你已经掌握了
|
|
746
|
+
你已经掌握了SchemaI-DSL的核心用法!
|
|
747
747
|
|
|
748
748
|
**核心要点**:
|
|
749
749
|
1. ✅ DSL语法简洁直观
|
package/docs/troubleshooting.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 常见问题排查指南
|
|
2
2
|
|
|
3
|
-
> **用途**: 快速解决
|
|
3
|
+
> **用途**: 快速解决 SchemaI-DSL 使用中的常见问题
|
|
4
4
|
> **更新**: 2025-12-26
|
|
5
5
|
|
|
6
6
|
---
|
|
@@ -378,7 +378,7 @@ db.createCollection('users', {
|
|
|
378
378
|
|
|
379
379
|
**解决方案**:
|
|
380
380
|
```javascript
|
|
381
|
-
//
|
|
381
|
+
// SchemaI-DSL 默认会自动安装 String 扩展
|
|
382
382
|
// 如果未生效,手动安装:
|
|
383
383
|
const { installStringExtensions } = require('schema-dsl');
|
|
384
384
|
installStringExtensions();
|
package/docs/type-reference.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
### 基本类型
|
|
10
10
|
|
|
11
|
-
| 类型 |
|
|
11
|
+
| 类型 | SchemaI-DSL | JSON Schema | 说明 |
|
|
12
12
|
|------|----------|-------------|------|
|
|
13
13
|
| 字符串 | `string` | `{ type: 'string' }` | 文本类型 |
|
|
14
14
|
| 数字 | `number` | `{ type: 'number' }` | 浮点数 |
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
### 格式类型(基于 string)
|
|
25
25
|
|
|
26
|
-
| 类型 |
|
|
26
|
+
| 类型 | SchemaI-DSL | JSON Schema format | 说明 |
|
|
27
27
|
|------|----------|-------------------|------|
|
|
28
28
|
| 邮箱 | `email` | `email` | 邮箱地址 |
|
|
29
29
|
| URL | `url` | `uri` | 网址 |
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
### 特殊类型
|
|
40
40
|
|
|
41
|
-
| 类型 |
|
|
41
|
+
| 类型 | SchemaI-DSL | JSON Schema | 说明 |
|
|
42
42
|
|------|----------|-------------|------|
|
|
43
43
|
| 二进制 | `binary` | `contentEncoding: base64` | Base64编码 |
|
|
44
44
|
| ObjectId | `objectId` | `pattern: ^[0-9a-fA-F]{24}$` | MongoDB ObjectId |
|
|
@@ -156,7 +156,7 @@ const schema = dsl({
|
|
|
156
156
|
|
|
157
157
|
### 完整对照表
|
|
158
158
|
|
|
159
|
-
| joi |
|
|
159
|
+
| joi | SchemaI-DSL | 说明 |
|
|
160
160
|
|-----|--------------|------|
|
|
161
161
|
| `Joi.string()` | `'string'` | 字符串 |
|
|
162
162
|
| `Joi.string().email()` | `'email'` | 邮箱 |
|
|
@@ -206,7 +206,7 @@ const schema = dsl({
|
|
|
206
206
|
|
|
207
207
|
### Q2: 为什么 `integer` 不是 `number().integer()`?
|
|
208
208
|
|
|
209
|
-
A:
|
|
209
|
+
A: SchemaI-DSL 使用 JSON Schema 标准,`integer` 是独立类型。
|
|
210
210
|
|
|
211
211
|
### Q3: 不支持简写吗?
|
|
212
212
|
|
package/docs/typescript-guide.md
CHANGED
|
@@ -479,12 +479,11 @@ const schema = dsl({
|
|
|
479
479
|
const schema = dsl({
|
|
480
480
|
userType: dsl('string!').label('用户类型'),
|
|
481
481
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
})
|
|
482
|
+
// 使用 dsl.match() 根据 userType 字段动态验证
|
|
483
|
+
companyName: dsl.match('userType', {
|
|
484
|
+
'company': 'string!', // 企业用户必填
|
|
485
|
+
'_default': 'string' // 个人用户可选
|
|
486
|
+
})
|
|
488
487
|
});
|
|
489
488
|
```
|
|
490
489
|
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# 一个字段支持多种类型
|
|
2
|
+
|
|
3
|
+
> 使用 `.pattern()` 方法匹配多种格式
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 基本用法
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
const { dsl, validate } = require('schema-dsl');
|
|
11
|
+
|
|
12
|
+
// 邮箱 或 手机号
|
|
13
|
+
const schema = dsl({
|
|
14
|
+
contact: dsl('string!')
|
|
15
|
+
.pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
|
|
16
|
+
.messages({ pattern: '必须是邮箱或手机号' })
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
validate(schema, { contact: 'test@example.com' }); // ✅
|
|
20
|
+
validate(schema, { contact: '13800138000' }); // ✅
|
|
21
|
+
validate(schema, { contact: 'invalid' }); // ❌
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**说明**:
|
|
25
|
+
- 正则中使用 `|` 表示"或",括号 `()` 分组
|
|
26
|
+
- 使用 `.messages()` 设置错误消息,支持多语言
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 常用示例
|
|
31
|
+
|
|
32
|
+
### 用户登录(用户名或邮箱)
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const loginSchema = dsl({
|
|
36
|
+
username: dsl('string:3-32!')
|
|
37
|
+
.pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|[a-zA-Z0-9_]+)$/)
|
|
38
|
+
.messages({ pattern: '必须是邮箱或用户名' }),
|
|
39
|
+
password: 'string:8-32!'
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 联系方式(邮箱或手机号)
|
|
44
|
+
|
|
45
|
+
```javascript
|
|
46
|
+
const schema = dsl({
|
|
47
|
+
contact: dsl('string!')
|
|
48
|
+
.pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
|
|
49
|
+
.messages({ pattern: '必须是邮箱或手机号' })
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### URL(http 或 https)
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
const schema = dsl({
|
|
57
|
+
website: dsl('string!')
|
|
58
|
+
.pattern(/^https?:\/\/.+$/)
|
|
59
|
+
.messages({ pattern: '必须是 http 或 https 开头的 URL' })
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 支持多语言
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
// 使用多语言 key
|
|
69
|
+
const schema = dsl({
|
|
70
|
+
contact: dsl('string!')
|
|
71
|
+
.pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
|
|
72
|
+
.messages({ pattern: 'pattern.emailOrPhone' }) // 多语言 key
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// 验证时指定语言
|
|
76
|
+
validate(schema, { contact: 'invalid' }, { locale: 'zh-CN' }); // 中文:必须是邮箱或手机号
|
|
77
|
+
validate(schema, { contact: 'invalid' }, { locale: 'en-US' }); // 英文:Must be an email or phone number
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**内置多语言 key**:
|
|
81
|
+
- `pattern.emailOrPhone` - 邮箱或手机号
|
|
82
|
+
- `pattern.usernameOrEmail` - 用户名或邮箱
|
|
83
|
+
- `pattern.httpOrHttps` - http 或 https URL
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 正则表达式速查
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// 邮箱 或 手机号
|
|
91
|
+
/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/
|
|
92
|
+
|
|
93
|
+
// http 或 https
|
|
94
|
+
/^https?:\/\/.+$/
|
|
95
|
+
|
|
96
|
+
// 用户名 或 邮箱
|
|
97
|
+
/^([^\s@]+@[^\s@]+\.[^\s@]+|[a-zA-Z0-9_]{3,32})$/
|
|
98
|
+
|
|
99
|
+
// 数字ID 或 UUID
|
|
100
|
+
/^(\d+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i
|
|
101
|
+
|
|
102
|
+
// 多个邮箱域名
|
|
103
|
+
/^[^\s@]+@(gmail\.com|qq\.com|163\.com)$/
|
|
104
|
+
|
|
105
|
+
// 中国或美国手机号
|
|
106
|
+
/^(1[3-9]\d{9}|\+1\d{10})$/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
## 完整示例
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
const { dsl, validate } = require('schema-dsl');
|
|
116
|
+
|
|
117
|
+
const registerSchema = dsl({
|
|
118
|
+
name: 'string:1-50!',
|
|
119
|
+
contact: dsl('string!')
|
|
120
|
+
.pattern(/^([^\s@]+@[^\s@]+\.[^\s@]+|1[3-9]\d{9})$/)
|
|
121
|
+
.messages({ pattern: '必须是邮箱或手机号' })
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const testData = [
|
|
125
|
+
{ name: '张三', contact: 'zhangsan@example.com' },
|
|
126
|
+
{ name: '李四', contact: '13800138000' },
|
|
127
|
+
{ name: '王五', contact: 'invalid' }
|
|
128
|
+
];
|
|
129
|
+
|
|
130
|
+
testData.forEach((data, index) => {
|
|
131
|
+
const result = validate(registerSchema, data);
|
|
132
|
+
console.log(`测试${index + 1}:`, result.valid ? '✅' : '❌');
|
|
133
|
+
if (!result.valid) {
|
|
134
|
+
console.log(' 错误:', result.errors[0].message);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**输出**:
|
|
140
|
+
```
|
|
141
|
+
测试1: ✅
|
|
142
|
+
测试2: ✅
|
|
143
|
+
测试3: ❌
|
|
144
|
+
错误: 必须是邮箱或手机号
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
|