schema-dsl 2.3.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.
- package/.eslintignore +10 -0
- package/.eslintrc.json +27 -0
- package/.github/CODE_OF_CONDUCT.md +45 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +57 -0
- package/.github/ISSUE_TEMPLATE/config.yml +11 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +45 -0
- package/.github/ISSUE_TEMPLATE/question.md +31 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +70 -0
- package/.github/SECURITY.md +184 -0
- package/.github/workflows/ci.yml +35 -0
- package/CHANGELOG.md +633 -0
- package/CONTRIBUTING.md +368 -0
- package/LICENSE +21 -0
- package/README.md +1122 -0
- package/STATUS.md +273 -0
- package/docs/FEATURE-INDEX.md +521 -0
- package/docs/INDEX.md +224 -0
- package/docs/api-reference.md +1098 -0
- package/docs/best-practices.md +672 -0
- package/docs/cache-manager.md +336 -0
- package/docs/design-philosophy.md +602 -0
- package/docs/dsl-syntax.md +654 -0
- package/docs/dynamic-locale.md +552 -0
- package/docs/error-handling.md +703 -0
- package/docs/export-guide.md +459 -0
- package/docs/faq.md +576 -0
- package/docs/frontend-i18n-guide.md +290 -0
- package/docs/i18n-user-guide.md +488 -0
- package/docs/label-vs-description.md +262 -0
- package/docs/markdown-exporter.md +398 -0
- package/docs/mongodb-exporter.md +279 -0
- package/docs/multi-type-support.md +319 -0
- package/docs/mysql-exporter.md +257 -0
- package/docs/plugin-system.md +542 -0
- package/docs/postgresql-exporter.md +290 -0
- package/docs/quick-start.md +761 -0
- package/docs/schema-helper.md +340 -0
- package/docs/schema-utils.md +492 -0
- package/docs/string-extensions.md +480 -0
- package/docs/troubleshooting.md +471 -0
- package/docs/type-converter.md +319 -0
- package/docs/type-reference.md +219 -0
- package/docs/validate.md +486 -0
- package/docs/validation-guide.md +484 -0
- package/examples/array-dsl-example.js +227 -0
- package/examples/custom-extension.js +85 -0
- package/examples/dsl-match-example.js +74 -0
- package/examples/dsl-style.js +118 -0
- package/examples/dynamic-locale-configuration.js +348 -0
- package/examples/dynamic-locale-example.js +287 -0
- package/examples/export-demo.js +130 -0
- package/examples/i18n-full-demo.js +310 -0
- package/examples/i18n-memory-safety.examples.js +268 -0
- package/examples/markdown-export.js +71 -0
- package/examples/middleware-usage.js +93 -0
- package/examples/password-reset/README.md +153 -0
- package/examples/password-reset/schema.js +26 -0
- package/examples/password-reset/test.js +101 -0
- package/examples/plugin-system.examples.js +205 -0
- package/examples/simple-example.js +122 -0
- package/examples/string-extensions.js +297 -0
- package/examples/user-registration/README.md +156 -0
- package/examples/user-registration/routes.js +92 -0
- package/examples/user-registration/schema.js +150 -0
- package/examples/user-registration/server.js +74 -0
- package/index.d.ts +1999 -0
- package/index.js +270 -0
- package/index.mjs +30 -0
- package/lib/adapters/DslAdapter.js +653 -0
- package/lib/adapters/index.js +20 -0
- package/lib/config/constants.js +286 -0
- package/lib/config/patterns/creditCard.js +9 -0
- package/lib/config/patterns/idCard.js +9 -0
- package/lib/config/patterns/index.js +8 -0
- package/lib/config/patterns/licensePlate.js +4 -0
- package/lib/config/patterns/passport.js +4 -0
- package/lib/config/patterns/phone.js +9 -0
- package/lib/config/patterns/postalCode.js +5 -0
- package/lib/core/CacheManager.js +376 -0
- package/lib/core/DslBuilder.js +740 -0
- package/lib/core/ErrorCodes.js +233 -0
- package/lib/core/ErrorFormatter.js +342 -0
- package/lib/core/JSONSchemaCore.js +347 -0
- package/lib/core/Locale.js +119 -0
- package/lib/core/MessageTemplate.js +89 -0
- package/lib/core/PluginManager.js +448 -0
- package/lib/core/StringExtensions.js +209 -0
- package/lib/core/Validator.js +316 -0
- package/lib/exporters/MarkdownExporter.js +420 -0
- package/lib/exporters/MongoDBExporter.js +162 -0
- package/lib/exporters/MySQLExporter.js +212 -0
- package/lib/exporters/PostgreSQLExporter.js +289 -0
- package/lib/exporters/index.js +24 -0
- package/lib/locales/en-US.js +65 -0
- package/lib/locales/es-ES.js +66 -0
- package/lib/locales/fr-FR.js +66 -0
- package/lib/locales/index.js +8 -0
- package/lib/locales/ja-JP.js +66 -0
- package/lib/locales/zh-CN.js +93 -0
- package/lib/utils/LRUCache.js +174 -0
- package/lib/utils/SchemaHelper.js +240 -0
- package/lib/utils/SchemaUtils.js +313 -0
- package/lib/utils/TypeConverter.js +245 -0
- package/lib/utils/index.js +13 -0
- package/lib/validators/CustomKeywords.js +203 -0
- package/lib/validators/index.js +11 -0
- package/package.json +70 -0
- package/plugins/custom-format.js +101 -0
- package/plugins/custom-validator.js +200 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
# Schema 工具函数文档
|
|
2
|
+
|
|
3
|
+
> **更新时间**: 2025-12-25
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 📑 目录
|
|
8
|
+
|
|
9
|
+
- [Schema 复用](#schema-复用)
|
|
10
|
+
- [Schema 合并](#schema-合并)
|
|
11
|
+
- [Schema 筛选](#schema-筛选)
|
|
12
|
+
- [Schema 导出](#schema-导出)
|
|
13
|
+
- [性能监控](#性能监控)
|
|
14
|
+
- [完整示例](#完整示例)
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Schema 复用
|
|
19
|
+
|
|
20
|
+
### 直接复用(最简单)✅
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
const { dsl } = require('schema-dsl');
|
|
24
|
+
|
|
25
|
+
// 定义可复用字段(就是普通对象)
|
|
26
|
+
const commonFields = {
|
|
27
|
+
email: 'email!'.label('邮箱地址'),
|
|
28
|
+
phone: 'string:11!'.phone('cn').label('手机号'),
|
|
29
|
+
username: 'string:3-32!'.username().label('用户名')
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// 直接使用
|
|
33
|
+
const registerSchema = dsl({
|
|
34
|
+
...commonFields, // ✅ 直接展开
|
|
35
|
+
password: 'string:8-64!'.password('strong')
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const profileSchema = dsl({
|
|
39
|
+
...commonFields, // ✅ 重复使用
|
|
40
|
+
bio: 'string:500',
|
|
41
|
+
avatar: 'url'
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**优点**: 最简单,直接使用 JavaScript 对象展开
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
### 函数复用(需要参数时)
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
// 定义可复用字段函数
|
|
53
|
+
const createEmailField = (label = '邮箱地址') =>
|
|
54
|
+
'email!'.label(label);
|
|
55
|
+
|
|
56
|
+
const createRangeField = (min, max) =>
|
|
57
|
+
`number:${min}-${max}`.label('数值范围');
|
|
58
|
+
|
|
59
|
+
// 使用
|
|
60
|
+
const schema = dsl({
|
|
61
|
+
email: createEmailField('联系邮箱'),
|
|
62
|
+
workEmail: createEmailField('工作邮箱'),
|
|
63
|
+
age: createRangeField(18, 120),
|
|
64
|
+
score: createRangeField(0, 100)
|
|
65
|
+
});
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**优点**: 支持参数化,灵活性强
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### 字段库复用(大型项目)
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
// fields/common.js - 定义字段库
|
|
76
|
+
module.exports = {
|
|
77
|
+
email: () => 'email!'.label('邮箱地址'),
|
|
78
|
+
phone: (country = 'cn') => `string:11!`.phone(country).label('手机号'),
|
|
79
|
+
username: (range = '3-32') => `string:${range}!`.username(range).label('用户名'),
|
|
80
|
+
password: (strength = 'medium') => 'string:8-64!'.password(strength).label('密码'),
|
|
81
|
+
|
|
82
|
+
// 组合字段
|
|
83
|
+
userAuth: () => ({
|
|
84
|
+
username: 'string:3-32!'.username().label('用户名'),
|
|
85
|
+
password: 'string:8-64!'.password('strong').label('密码')
|
|
86
|
+
}),
|
|
87
|
+
|
|
88
|
+
userProfile: () => ({
|
|
89
|
+
nickname: 'string:2-20!'.label('昵称'),
|
|
90
|
+
bio: 'string:500',
|
|
91
|
+
avatar: 'url'
|
|
92
|
+
})
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// 使用
|
|
96
|
+
const fields = require('./fields/common');
|
|
97
|
+
|
|
98
|
+
const loginSchema = dsl({
|
|
99
|
+
email: fields.email(),
|
|
100
|
+
password: fields.password('strong')
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const registerSchema = dsl({
|
|
104
|
+
...fields.userAuth(), // ✅ 展开组合字段
|
|
105
|
+
email: fields.email(),
|
|
106
|
+
phone: fields.phone('cn')
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**优点**: 统一管理,易于维护
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Schema 合并
|
|
115
|
+
|
|
116
|
+
### merge() - 合并多个Schema
|
|
117
|
+
|
|
118
|
+
```javascript
|
|
119
|
+
const { SchemaUtils, dsl } = require('schema-dsl');
|
|
120
|
+
|
|
121
|
+
// 基础Schema
|
|
122
|
+
const baseUser = dsl({
|
|
123
|
+
name: 'string:1-50!',
|
|
124
|
+
email: 'email!'
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// 扩展Schema
|
|
128
|
+
const withAge = dsl({
|
|
129
|
+
age: 'number:18-120',
|
|
130
|
+
gender: 'male|female|other'
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const withProfile = dsl({
|
|
134
|
+
bio: 'string:500',
|
|
135
|
+
avatar: 'url'
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// 合并
|
|
139
|
+
const fullUser = SchemaUtils.merge(baseUser, withAge, withProfile);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**说明**: 合并 properties 和 required 数组,自动去重
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### extend() - 扩展Schema(继承)
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
const baseUser = dsl({
|
|
150
|
+
name: 'string!',
|
|
151
|
+
email: 'email!'
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// 扩展基础Schema
|
|
155
|
+
const admin = SchemaUtils.extend(baseUser, {
|
|
156
|
+
role: 'admin|superadmin',
|
|
157
|
+
permissions: 'array<string>'
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// admin包含所有baseUser字段 + role + permissions
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**说明**: 类似继承,保留基础Schema的所有字段
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Schema 筛选
|
|
168
|
+
|
|
169
|
+
### pick() - 选择字段
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
const fullUser = dsl({
|
|
173
|
+
name: 'string!',
|
|
174
|
+
email: 'email!',
|
|
175
|
+
password: 'string:8-64!',
|
|
176
|
+
phone: 'string:11!',
|
|
177
|
+
age: 'number:18-120'
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 只选择特定字段
|
|
181
|
+
const publicUser = SchemaUtils.pick(fullUser, ['name', 'email']);
|
|
182
|
+
|
|
183
|
+
// publicUser 只包含 name 和 email
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**用途**: 从完整Schema中提取部分字段(如公开信息)
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### omit() - 排除字段
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
const fullUser = dsl({
|
|
194
|
+
name: 'string!',
|
|
195
|
+
email: 'email!',
|
|
196
|
+
password: 'string:8-64!',
|
|
197
|
+
phone: 'string:11!'
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// 排除敏感字段
|
|
201
|
+
const safeUser = SchemaUtils.omit(fullUser, ['password']);
|
|
202
|
+
|
|
203
|
+
// safeUser 包含除 password 外的所有字段
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**用途**: 移除敏感字段(如密码)
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Schema 导出
|
|
211
|
+
|
|
212
|
+
### toMarkdown() - 导出为Markdown文档
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
const schema = dsl({
|
|
216
|
+
username: 'string:3-32!'.label('用户名'),
|
|
217
|
+
email: 'email!'.label('邮箱地址'),
|
|
218
|
+
age: 'number:18-120'
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const markdown = SchemaUtils.toMarkdown(schema, {
|
|
222
|
+
title: '用户注册Schema',
|
|
223
|
+
showRequired: true,
|
|
224
|
+
showType: true,
|
|
225
|
+
showConstraints: true
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
console.log(markdown);
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**输出**:
|
|
232
|
+
```markdown
|
|
233
|
+
# 用户注册Schema
|
|
234
|
+
|
|
235
|
+
| 字段 | 类型 | 必填 | 约束 | 说明 |
|
|
236
|
+
|------|------|------|------|------|
|
|
237
|
+
| username | string | ✅ | 3-32字符 | 用户名 |
|
|
238
|
+
| email | email | ✅ | - | 邮箱地址 |
|
|
239
|
+
| age | number | ❌ | 18-120 | - |
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**用途**: 生成API文档
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
### toHTML() - 导出为HTML表格
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
const html = SchemaUtils.toHTML(schema, {
|
|
250
|
+
title: '用户注册Schema',
|
|
251
|
+
theme: 'bootstrap' // 或 'default'
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// 生成HTML表格,可以嵌入文档
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**用途**: 集成到Web文档
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 性能监控
|
|
262
|
+
|
|
263
|
+
### validateBatch() - 批量验证
|
|
264
|
+
|
|
265
|
+
```javascript
|
|
266
|
+
const { Validator } = require('schema-dsl');
|
|
267
|
+
|
|
268
|
+
const schema = dsl({
|
|
269
|
+
email: 'email!',
|
|
270
|
+
age: 'number:18-120'
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const validator = new Validator();
|
|
274
|
+
|
|
275
|
+
const items = [
|
|
276
|
+
{ email: 'user1@example.com', age: 25 },
|
|
277
|
+
{ email: 'invalid', age: 15 },
|
|
278
|
+
{ email: 'user2@example.com', age: 30 }
|
|
279
|
+
];
|
|
280
|
+
|
|
281
|
+
const results = validator.validateBatch(schema, items);
|
|
282
|
+
|
|
283
|
+
console.log(results);
|
|
284
|
+
// {
|
|
285
|
+
// results: [
|
|
286
|
+
// { valid: true, ... },
|
|
287
|
+
// { valid: false, errors: [...] },
|
|
288
|
+
// { valid: true, ... }
|
|
289
|
+
// ],
|
|
290
|
+
// stats: {
|
|
291
|
+
// total: 3,
|
|
292
|
+
// valid: 2,
|
|
293
|
+
// invalid: 1,
|
|
294
|
+
// duration: '5.2ms'
|
|
295
|
+
// }
|
|
296
|
+
// }
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**用途**: 批量验证数据,获取性能统计
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
### 性能监控(自动)
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
const validator = new Validator({ performance: true });
|
|
307
|
+
|
|
308
|
+
const result = validator.validate(schema, data);
|
|
309
|
+
|
|
310
|
+
console.log(result.performance);
|
|
311
|
+
// {
|
|
312
|
+
// duration: '2.1ms',
|
|
313
|
+
// compileDuration: '1.5ms',
|
|
314
|
+
// validateDuration: '0.6ms'
|
|
315
|
+
// }
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**用途**: 监控验证性能
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 其他工具
|
|
323
|
+
|
|
324
|
+
### clone() - 深度克隆Schema
|
|
325
|
+
|
|
326
|
+
```javascript
|
|
327
|
+
const original = dsl({
|
|
328
|
+
user: {
|
|
329
|
+
name: 'string!',
|
|
330
|
+
profile: {
|
|
331
|
+
bio: 'string:500'
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const cloned = SchemaUtils.clone(original);
|
|
337
|
+
|
|
338
|
+
// cloned 是完全独立的副本
|
|
339
|
+
cloned.properties.user.properties.name.maxLength = 100;
|
|
340
|
+
// original 不会被修改
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
### validateNestingDepth() - 检查嵌套深度
|
|
346
|
+
|
|
347
|
+
```javascript
|
|
348
|
+
const schema = dsl({
|
|
349
|
+
level1: {
|
|
350
|
+
level2: {
|
|
351
|
+
level3: {
|
|
352
|
+
level4: 'string'
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const depth = schema.validateNestingDepth(10);
|
|
359
|
+
// 返回: 4
|
|
360
|
+
|
|
361
|
+
if (depth > 5) {
|
|
362
|
+
console.warn('嵌套层级过深,建议扁平化');
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
**用途**: 防止过深嵌套
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 完整示例
|
|
371
|
+
|
|
372
|
+
### 企业级字段库
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
// libs/fields/index.js
|
|
376
|
+
module.exports = {
|
|
377
|
+
// 基础字段
|
|
378
|
+
id: () => 'string!'.pattern(/^[a-zA-Z0-9_-]+$/).label('ID'),
|
|
379
|
+
email: () => 'email!'.label('邮箱地址'),
|
|
380
|
+
phone: (country = 'cn') => 'string:11!'.phone(country).label('手机号'),
|
|
381
|
+
|
|
382
|
+
// 认证字段
|
|
383
|
+
auth: {
|
|
384
|
+
username: () => 'string:3-32!'.username().label('用户名'),
|
|
385
|
+
password: (strength = 'strong') =>
|
|
386
|
+
'string:8-64!'.password(strength).label('密码')
|
|
387
|
+
},
|
|
388
|
+
|
|
389
|
+
// 个人信息
|
|
390
|
+
profile: {
|
|
391
|
+
nickname: () => 'string:2-20!'.label('昵称'),
|
|
392
|
+
realName: () => 'string:2-50'.label('真实姓名'),
|
|
393
|
+
bio: () => 'string:500',
|
|
394
|
+
avatar: () => 'url'.label('头像'),
|
|
395
|
+
birthday: () => 'date'
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
// 地址信息
|
|
399
|
+
address: () => ({
|
|
400
|
+
country: 'string:2-50!',
|
|
401
|
+
province: 'string:2-50!',
|
|
402
|
+
city: 'string:2-50!',
|
|
403
|
+
detail: 'string:10-200!'
|
|
404
|
+
}),
|
|
405
|
+
|
|
406
|
+
// 时间戳
|
|
407
|
+
timestamps: () => ({
|
|
408
|
+
created_at: 'datetime!',
|
|
409
|
+
updated_at: 'datetime!'
|
|
410
|
+
})
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
// 使用
|
|
414
|
+
const fields = require('./libs/fields');
|
|
415
|
+
|
|
416
|
+
// 用户注册
|
|
417
|
+
const registerSchema = dsl({
|
|
418
|
+
...fields.auth,
|
|
419
|
+
email: fields.email(),
|
|
420
|
+
phone: fields.phone('cn'),
|
|
421
|
+
agree: 'boolean!'
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
// 用户资料
|
|
425
|
+
const profileSchema = dsl({
|
|
426
|
+
...fields.profile,
|
|
427
|
+
...fields.timestamps()
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
// 完整用户
|
|
431
|
+
const userSchema = SchemaUtils.merge(
|
|
432
|
+
registerSchema,
|
|
433
|
+
profileSchema,
|
|
434
|
+
dsl(fields.address())
|
|
435
|
+
);
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## 最佳实践
|
|
441
|
+
|
|
442
|
+
### 1. 小项目:直接复用
|
|
443
|
+
|
|
444
|
+
```javascript
|
|
445
|
+
const commonFields = {
|
|
446
|
+
email: 'email!'.label('邮箱'),
|
|
447
|
+
phone: 'string:11!'.phone('cn')
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
const schema1 = dsl({ ...commonFields, ... });
|
|
451
|
+
const schema2 = dsl({ ...commonFields, ... });
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### 2. 中型项目:函数复用
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
const createUserFields = (options = {}) => ({
|
|
458
|
+
email: 'email!'.label(options.emailLabel || '邮箱'),
|
|
459
|
+
phone: 'string:11!'.phone(options.country || 'cn')
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
const schema = dsl({
|
|
463
|
+
...createUserFields({ emailLabel: '联系邮箱' }),
|
|
464
|
+
...otherFields
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### 3. 大型项目:字段库
|
|
469
|
+
|
|
470
|
+
```javascript
|
|
471
|
+
// 统一管理在 fields/ 目录
|
|
472
|
+
const fields = require('./fields');
|
|
473
|
+
|
|
474
|
+
const schema = dsl({
|
|
475
|
+
...fields.auth,
|
|
476
|
+
...fields.profile
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## 相关文档
|
|
483
|
+
|
|
484
|
+
- [DSL 语法](./dsl-syntax.md)
|
|
485
|
+
- [String 扩展](./string-extensions.md)
|
|
486
|
+
- [API 参考](./api-reference.md)
|
|
487
|
+
|
|
488
|
+
---
|
|
489
|
+
|
|
490
|
+
**最后更新**: 2025-12-25
|
|
491
|
+
|
|
492
|
+
|