schema-dsl 1.2.4 → 2.0.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/CHANGELOG.md +87 -210
- package/README.md +391 -2249
- package/dist/DslBuilder-DQDN0ZxZ.d.cts +341 -0
- package/dist/DslBuilder-DkLaOo9Q.d.ts +341 -0
- package/dist/Validator-C7GsVQOH.d.cts +192 -0
- package/dist/Validator-hFWKGxir.d.ts +192 -0
- package/dist/index.cjs +6594 -0
- package/dist/index.d.cts +1145 -0
- package/dist/index.d.ts +1145 -0
- package/dist/index.js +6528 -0
- package/dist/plugin-CIKtTMtS.d.cts +246 -0
- package/dist/plugin-CIKtTMtS.d.ts +246 -0
- package/dist/plugins/custom-format.cjs +3802 -0
- package/dist/plugins/custom-format.d.cts +12 -0
- package/dist/plugins/custom-format.d.ts +12 -0
- package/dist/plugins/custom-format.js +3772 -0
- package/dist/plugins/custom-type-example.cjs +3795 -0
- package/dist/plugins/custom-type-example.d.cts +8 -0
- package/dist/plugins/custom-type-example.d.ts +8 -0
- package/dist/plugins/custom-type-example.js +3765 -0
- package/dist/plugins/custom-validator.cjs +146 -0
- package/dist/plugins/custom-validator.d.cts +10 -0
- package/dist/plugins/custom-validator.d.ts +10 -0
- package/dist/plugins/custom-validator.js +121 -0
- package/docs/FEATURE-INDEX.md +102 -68
- package/docs/add-custom-locale.md +48 -35
- package/docs/add-keyword.md +24 -0
- package/docs/api-reference.md +396 -154
- package/docs/api.md +13 -0
- package/docs/best-practices-project-structure.md +19 -10
- package/docs/best-practices.md +93 -53
- package/docs/cache-manager.md +23 -15
- package/docs/compile.md +45 -0
- package/docs/conditional-api.md +40 -11
- package/docs/custom-extensions-guide.md +80 -152
- package/docs/design-philosophy.md +76 -71
- package/docs/doc-index.md +324 -0
- package/docs/dsl-syntax.md +69 -19
- package/docs/dynamic-locale.md +24 -14
- package/docs/enum.md +12 -5
- package/docs/error-handling.md +53 -44
- package/docs/export-guide.md +47 -8
- package/docs/export-limitations.md +27 -11
- package/docs/faq.md +86 -67
- package/docs/frontend-i18n-guide.md +26 -12
- package/docs/i18n-user-guide.md +60 -47
- package/docs/i18n.md +51 -32
- package/docs/index.md +48 -0
- package/docs/json-schema-basics.md +40 -0
- package/docs/label-vs-description.md +12 -3
- package/docs/markdown-exporter.md +15 -6
- package/docs/mongodb-exporter.md +11 -4
- package/docs/multi-language.md +26 -0
- package/docs/multi-type-support.md +26 -33
- package/docs/mysql-exporter.md +9 -2
- package/docs/number-operators.md +12 -5
- package/docs/optional-marker-guide.md +28 -23
- package/docs/performance-guide.md +49 -0
- package/docs/plugin-system.md +205 -366
- package/docs/plugin-type-registration.md +34 -0
- package/docs/postgresql-exporter.md +9 -2
- package/docs/public/favicon.svg +5 -0
- package/docs/quick-start.md +37 -363
- package/docs/runtime-locale-support.md +20 -9
- package/docs/schema-helper.md +10 -5
- package/docs/schema-utils-advanced-issues.md +23 -0
- package/docs/schema-utils-best-practices.md +20 -0
- package/docs/schema-utils-chaining.md +7 -0
- package/docs/schema-utils.md +76 -42
- package/docs/security-checklist.md +20 -0
- package/docs/string-extensions.md +17 -9
- package/docs/troubleshooting.md +36 -21
- package/docs/type-converter.md +41 -50
- package/docs/type-reference.md +38 -15
- package/docs/typescript-guide.md +53 -42
- package/docs/union-type-guide.md +11 -1
- package/docs/union-types.md +10 -3
- package/docs/validate-async.md +36 -25
- package/docs/validate-batch.md +49 -0
- package/docs/validate-dsl-object-support.md +33 -28
- package/docs/validate.md +36 -16
- package/docs/validation-guide.md +25 -7
- package/docs/validator.md +39 -0
- package/package.json +85 -27
- package/plugins/custom-format.cjs +8 -0
- package/plugins/custom-type-example.cjs +8 -0
- package/plugins/custom-validator.cjs +8 -0
- package/src/adapters/DslAdapter.ts +111 -0
- package/src/adapters/index.ts +1 -0
- package/src/config/constants.ts +83 -0
- package/src/config/index.ts +2 -0
- package/src/config/patterns.ts +77 -0
- package/src/core/CacheManager.ts +159 -0
- package/src/core/ConditionalBuilder.ts +382 -0
- package/src/core/ConditionalRuntime.ts +28 -0
- package/src/core/ConditionalValidator.ts +255 -0
- package/src/core/DslBuilder.ts +677 -0
- package/src/core/ErrorCodes.ts +38 -0
- package/src/core/ErrorFormatter.ts +271 -0
- package/src/core/JSONSchemaCore.ts +65 -0
- package/src/core/Locale.ts +187 -0
- package/src/core/MessageTemplate.ts +42 -0
- package/src/core/ObjectDslBuilder.ts +64 -0
- package/src/core/PluginManager.ts +326 -0
- package/src/core/StringExtensions.ts +140 -0
- package/src/core/TemplateEngine.ts +44 -0
- package/src/core/Validator.ts +448 -0
- package/src/errors/I18nError.ts +159 -0
- package/src/errors/ValidationError.ts +105 -0
- package/src/exporters/BaseExporter.ts +60 -0
- package/src/exporters/MarkdownExporter.ts +305 -0
- package/src/exporters/MongoDBExporter.ts +126 -0
- package/src/exporters/MySQLExporter.ts +155 -0
- package/src/exporters/PostgreSQLExporter.ts +222 -0
- package/src/exporters/index.ts +18 -0
- package/src/index.ts +633 -0
- package/{lib/locales/en-US.js → src/locales/en-US.ts} +21 -37
- package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +63 -16
- package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +74 -27
- package/src/locales/index.ts +103 -0
- package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +59 -17
- package/src/locales/types.ts +156 -0
- package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +21 -38
- package/src/parser/ConstraintParser.ts +101 -0
- package/src/parser/DslParser.ts +470 -0
- package/src/parser/SchemaCompiler.ts +66 -0
- package/src/parser/TypeRegistry.ts +250 -0
- package/src/parser/index.ts +6 -0
- package/src/plugins/custom-format.ts +126 -0
- package/src/plugins/custom-type-example.ts +108 -0
- package/src/plugins/custom-validator.ts +140 -0
- package/src/types/conditional.ts +28 -0
- package/src/types/config.ts +59 -0
- package/src/types/dsl.ts +131 -0
- package/src/types/error.ts +60 -0
- package/src/types/index.ts +17 -0
- package/src/types/infer.ts +128 -0
- package/src/types/plugin.ts +58 -0
- package/src/types/safe-regex.d.ts +9 -0
- package/src/types/schema.ts +66 -0
- package/src/types/validate.ts +71 -0
- package/src/utils/SchemaHelper.ts +196 -0
- package/src/utils/SchemaUtils.ts +346 -0
- package/src/utils/TypeConverter.ts +215 -0
- package/src/utils/index.ts +10 -0
- package/src/validators/CustomKeywords.ts +477 -0
- package/.eslintignore +0 -11
- package/.eslintrc.json +0 -27
- package/CONTRIBUTING.md +0 -368
- package/STATUS.md +0 -491
- package/changelogs/v1.0.0.md +0 -328
- package/changelogs/v1.0.9.md +0 -367
- package/changelogs/v1.1.0.md +0 -389
- package/changelogs/v1.1.1.md +0 -308
- package/changelogs/v1.1.2.md +0 -183
- package/changelogs/v1.1.3.md +0 -161
- package/changelogs/v1.1.4.md +0 -432
- package/changelogs/v1.1.5.md +0 -493
- package/changelogs/v1.1.6.md +0 -211
- package/changelogs/v1.1.8.md +0 -376
- package/changelogs/v1.2.3.md +0 -124
- package/docs/INDEX.md +0 -252
- package/docs/issues-resolved-summary.md +0 -196
- package/docs/performance-benchmark-report.md +0 -179
- package/docs/performance-quick-reference.md +0 -123
- package/docs/user-questions-answered.md +0 -353
- package/docs/validation-rules-v1.0.2.md +0 -1608
- package/examples/README.md +0 -81
- package/examples/array-dsl-example.js +0 -227
- package/examples/conditional-example.js +0 -288
- package/examples/conditional-non-object.js +0 -129
- package/examples/conditional-validate-example.js +0 -321
- package/examples/custom-extension.js +0 -85
- package/examples/dsl-match-example.js +0 -74
- package/examples/dsl-style.js +0 -118
- package/examples/dynamic-locale-configuration.js +0 -348
- package/examples/dynamic-locale-example.js +0 -287
- package/examples/enum.examples.js +0 -324
- package/examples/export-demo.js +0 -130
- package/examples/express-integration.js +0 -376
- package/examples/i18n-error-handling-complete.js +0 -381
- package/examples/i18n-error-handling-quickstart.md +0 -0
- package/examples/i18n-error.examples.js +0 -181
- package/examples/i18n-full-demo.js +0 -301
- package/examples/i18n-memory-safety.examples.js +0 -268
- package/examples/markdown-export.js +0 -71
- package/examples/middleware-usage.js +0 -93
- package/examples/new-features-comparison.js +0 -315
- package/examples/password-reset/README.md +0 -153
- package/examples/password-reset/schema.js +0 -26
- package/examples/password-reset/test.js +0 -101
- package/examples/plugin-system.examples.js +0 -205
- package/examples/schema-utils-chaining.examples.js +0 -250
- package/examples/simple-example.js +0 -122
- package/examples/slug.examples.js +0 -179
- package/examples/string-extensions.js +0 -297
- package/examples/union-type-example.js +0 -127
- package/examples/union-types-example.js +0 -77
- package/examples/user-registration/README.md +0 -156
- package/examples/user-registration/routes.js +0 -92
- package/examples/user-registration/schema.js +0 -150
- package/examples/user-registration/server.js +0 -74
- package/index.d.ts +0 -3540
- package/index.js +0 -457
- package/index.mjs +0 -60
- package/lib/adapters/DslAdapter.js +0 -871
- package/lib/adapters/index.js +0 -20
- package/lib/config/constants.js +0 -286
- package/lib/config/patterns/common.js +0 -47
- package/lib/config/patterns/creditCard.js +0 -9
- package/lib/config/patterns/idCard.js +0 -9
- package/lib/config/patterns/index.js +0 -9
- package/lib/config/patterns/licensePlate.js +0 -4
- package/lib/config/patterns/passport.js +0 -4
- package/lib/config/patterns/phone.js +0 -9
- package/lib/config/patterns/postalCode.js +0 -5
- package/lib/core/CacheManager.js +0 -376
- package/lib/core/ConditionalBuilder.js +0 -503
- package/lib/core/DslBuilder.js +0 -1400
- package/lib/core/ErrorCodes.js +0 -233
- package/lib/core/ErrorFormatter.js +0 -445
- package/lib/core/JSONSchemaCore.js +0 -347
- package/lib/core/Locale.js +0 -130
- package/lib/core/MessageTemplate.js +0 -98
- package/lib/core/PluginManager.js +0 -448
- package/lib/core/StringExtensions.js +0 -240
- package/lib/core/Validator.js +0 -654
- package/lib/errors/I18nError.js +0 -328
- package/lib/errors/ValidationError.js +0 -191
- package/lib/exporters/MarkdownExporter.js +0 -420
- package/lib/exporters/MongoDBExporter.js +0 -162
- package/lib/exporters/MySQLExporter.js +0 -212
- package/lib/exporters/PostgreSQLExporter.js +0 -289
- package/lib/exporters/index.js +0 -24
- package/lib/locales/index.js +0 -8
- package/lib/utils/LRUCache.js +0 -174
- package/lib/utils/SchemaHelper.js +0 -240
- package/lib/utils/SchemaUtils.js +0 -445
- package/lib/utils/TypeConverter.js +0 -245
- package/lib/utils/index.js +0 -13
- package/lib/validators/CustomKeywords.js +0 -616
- package/lib/validators/index.js +0 -11
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# SchemaUtils 深入问题分析
|
|
2
|
+
|
|
3
|
+
## 常见问题
|
|
4
|
+
|
|
5
|
+
### 内部字段泄漏
|
|
6
|
+
|
|
7
|
+
链式 DSL 会产生 `_label`、`_customMessages`、`_required` 等内部字段。面向 OpenAPI 或外部系统时,应在 Builder 阶段使用 `toJsonSchema()` 输出纯净 JSON Schema。
|
|
8
|
+
|
|
9
|
+
### required 同步
|
|
10
|
+
|
|
11
|
+
使用 `pick()`、`omit()`、`partial()` 后应检查 `required` 是否符合预期,当前实现会同步处理顶层 required。
|
|
12
|
+
|
|
13
|
+
### 深拷贝限制
|
|
14
|
+
|
|
15
|
+
`SchemaUtils.clone()` 基于 JSON 序列化,不保留函数、`RegExp` 实例等非 JSON 值。
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 对应示例文件
|
|
20
|
+
|
|
21
|
+
**示例入口**: [schema-utils-advanced-issues.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/schema-utils-advanced-issues.ts)
|
|
22
|
+
**说明**: 覆盖内部字段泄漏、`required` 同步和 `clone()` 深拷贝边界三个最容易踩坑的点。
|
|
23
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# SchemaUtils 最佳实践
|
|
2
|
+
|
|
3
|
+
## 推荐用法
|
|
4
|
+
|
|
5
|
+
- 使用 `SchemaUtils.reusable()` 封装可复用字段工厂。
|
|
6
|
+
- 使用 `SchemaUtils.extend()` 组合基础 Schema 与业务扩展字段。
|
|
7
|
+
- 使用 `pick()` / `omit()` / `partial()` 生成派生 Schema,避免手写重复定义。
|
|
8
|
+
|
|
9
|
+
## 注意事项
|
|
10
|
+
|
|
11
|
+
- 派生 Schema 后仍需用 `validate()` 或 `Validator` 做回归验证。
|
|
12
|
+
- 对外导出标准 JSON Schema 时,优先在 Builder 阶段使用 `toJsonSchema()`,或在导出前显式清理内部字段。
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 对应示例文件
|
|
17
|
+
|
|
18
|
+
**示例入口**: [schema-utils-best-practices.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/schema-utils-best-practices.ts)
|
|
19
|
+
**说明**: 以创建、公开返回、局部更新三个场景展示字段库复用与派生 schema 的推荐组织方式。
|
|
20
|
+
|
|
@@ -140,4 +140,11 @@ app.patch('/users/:id', async (req, res, next) => {
|
|
|
140
140
|
### extend(schema, extensions)
|
|
141
141
|
扩展字段
|
|
142
142
|
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 对应示例文件
|
|
146
|
+
|
|
147
|
+
**示例入口**: [schema-utils-chaining.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/schema-utils-chaining.ts)
|
|
148
|
+
**说明**: 覆盖 `omit()`、`extend()`、`pick()`、`partial()` 的链式组合,以及派生 schema 的成功/失败验证路径。
|
|
149
|
+
|
|
143
150
|
|
package/docs/schema-utils.md
CHANGED
|
@@ -113,32 +113,33 @@ const registerSchema = dsl({
|
|
|
113
113
|
|
|
114
114
|
## Schema 合并
|
|
115
115
|
|
|
116
|
-
###
|
|
116
|
+
### createLibrary() - 创建片段库
|
|
117
117
|
|
|
118
118
|
```javascript
|
|
119
119
|
const { SchemaUtils, dsl } = require('schema-dsl');
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
121
|
+
const fields = SchemaUtils.createLibrary({
|
|
122
|
+
email: () => 'email!'.label('邮箱地址'),
|
|
123
|
+
phone: () => dsl('string!').phone('cn').label('手机号'),
|
|
124
|
+
profile: () => ({
|
|
125
|
+
bio: 'string:500',
|
|
126
|
+
avatar: 'url'
|
|
127
|
+
})
|
|
125
128
|
});
|
|
126
129
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
const registerSchema = dsl({
|
|
131
|
+
email: fields.email(),
|
|
132
|
+
phone: fields.phone(),
|
|
133
|
+
password: dsl('string!').password('strong')
|
|
131
134
|
});
|
|
132
135
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
bio: 'string:500',
|
|
137
|
-
avatar: 'url'
|
|
136
|
+
const profileSchema = dsl({
|
|
137
|
+
...fields.profile(),
|
|
138
|
+
email: fields.email()
|
|
138
139
|
});
|
|
139
140
|
```
|
|
140
141
|
|
|
141
|
-
**说明**:
|
|
142
|
+
**说明**: `createLibrary()` 只是返回片段工厂集合,适合在大型项目中集中管理字段和组合片段。
|
|
142
143
|
|
|
143
144
|
---
|
|
144
145
|
|
|
@@ -206,6 +207,32 @@ const safeUser = SchemaUtils.omit(fullUser, ['password']);
|
|
|
206
207
|
|
|
207
208
|
---
|
|
208
209
|
|
|
210
|
+
### partial() - 将字段改为可选
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
const updateSchema = SchemaUtils.partial(dsl({
|
|
214
|
+
name: 'string!',
|
|
215
|
+
email: 'email!',
|
|
216
|
+
age: 'number:18-120'
|
|
217
|
+
}));
|
|
218
|
+
|
|
219
|
+
// 结果中 required 会被移除,适合 PATCH / 局部更新场景
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
也可以只对部分字段做可选化:
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
const schema = dsl({
|
|
226
|
+
name: 'string!',
|
|
227
|
+
email: 'email!',
|
|
228
|
+
age: 'number:18-120'
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
const partialContact = SchemaUtils.partial(schema, ['name', 'email']);
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
209
236
|
## Schema 导出
|
|
210
237
|
|
|
211
238
|
### toMarkdown() - 导出为Markdown文档
|
|
@@ -218,10 +245,7 @@ const schema = dsl({
|
|
|
218
245
|
});
|
|
219
246
|
|
|
220
247
|
const markdown = SchemaUtils.toMarkdown(schema, {
|
|
221
|
-
title: '用户注册Schema'
|
|
222
|
-
showRequired: true,
|
|
223
|
-
showType: true,
|
|
224
|
-
showConstraints: true
|
|
248
|
+
title: '用户注册Schema'
|
|
225
249
|
});
|
|
226
250
|
|
|
227
251
|
console.log(markdown);
|
|
@@ -246,8 +270,7 @@ console.log(markdown);
|
|
|
246
270
|
|
|
247
271
|
```javascript
|
|
248
272
|
const html = SchemaUtils.toHTML(schema, {
|
|
249
|
-
title: '用户注册Schema'
|
|
250
|
-
theme: 'bootstrap' // 或 'default'
|
|
273
|
+
title: '用户注册Schema'
|
|
251
274
|
});
|
|
252
275
|
|
|
253
276
|
// 生成HTML表格,可以嵌入文档
|
|
@@ -259,10 +282,10 @@ const html = SchemaUtils.toHTML(schema, {
|
|
|
259
282
|
|
|
260
283
|
## 性能监控
|
|
261
284
|
|
|
262
|
-
### validateBatch() -
|
|
285
|
+
### validateBatch() - 批量验证统计
|
|
263
286
|
|
|
264
287
|
```javascript
|
|
265
|
-
const { Validator } = require('schema-dsl');
|
|
288
|
+
const { SchemaUtils, Validator, dsl } = require('schema-dsl');
|
|
266
289
|
|
|
267
290
|
const schema = dsl({
|
|
268
291
|
email: 'email!',
|
|
@@ -277,44 +300,46 @@ const items = [
|
|
|
277
300
|
{ email: 'user2@example.com', age: 30 }
|
|
278
301
|
];
|
|
279
302
|
|
|
280
|
-
const
|
|
303
|
+
const batch = SchemaUtils.validateBatch(schema, items, validator.getAjv());
|
|
281
304
|
|
|
282
|
-
console.log(
|
|
305
|
+
console.log(batch);
|
|
283
306
|
// {
|
|
284
307
|
// results: [
|
|
285
|
-
// { valid: true, ... },
|
|
286
|
-
// { valid: false, errors: [...] },
|
|
287
|
-
// { valid: true, ... }
|
|
308
|
+
// { index: 0, valid: true, errors: null, data: {...} },
|
|
309
|
+
// { index: 1, valid: false, errors: [...], data: null },
|
|
310
|
+
// { index: 2, valid: true, errors: null, data: {...} }
|
|
288
311
|
// ],
|
|
289
|
-
//
|
|
312
|
+
// summary: {
|
|
290
313
|
// total: 3,
|
|
291
314
|
// valid: 2,
|
|
292
315
|
// invalid: 1,
|
|
293
|
-
// duration:
|
|
316
|
+
// duration: 5,
|
|
317
|
+
// averageTime: 1.67
|
|
294
318
|
// }
|
|
295
319
|
// }
|
|
296
320
|
```
|
|
297
321
|
|
|
298
|
-
|
|
322
|
+
**说明**:
|
|
323
|
+
- 如果你只需要“每条是否通过”的结果,可直接使用 `validator.validateBatch(schema, items)`
|
|
324
|
+
- 如果你还需要汇总统计信息,再使用 `SchemaUtils.validateBatch(schema, items, validator.getAjv())`
|
|
299
325
|
|
|
300
326
|
---
|
|
301
327
|
|
|
302
|
-
###
|
|
328
|
+
### withPerformance() - 给 Validator 添加性能包装
|
|
303
329
|
|
|
304
330
|
```javascript
|
|
305
|
-
const validator = new Validator(
|
|
331
|
+
const validator = SchemaUtils.withPerformance(new Validator());
|
|
306
332
|
|
|
307
333
|
const result = validator.validate(schema, data);
|
|
308
334
|
|
|
309
335
|
console.log(result.performance);
|
|
310
336
|
// {
|
|
311
|
-
// duration:
|
|
312
|
-
//
|
|
313
|
-
// validateDuration: '0.6ms'
|
|
337
|
+
// duration: 2,
|
|
338
|
+
// timestamp: '2026-05-06T12:34:56.789Z'
|
|
314
339
|
// }
|
|
315
340
|
```
|
|
316
341
|
|
|
317
|
-
**用途**:
|
|
342
|
+
**用途**: 在不改业务调用方式的前提下,为验证结果附加耗时信息
|
|
318
343
|
|
|
319
344
|
---
|
|
320
345
|
|
|
@@ -344,6 +369,8 @@ cloned.properties.user.properties.name.maxLength = 100;
|
|
|
344
369
|
### validateNestingDepth() - 检查嵌套深度
|
|
345
370
|
|
|
346
371
|
```javascript
|
|
372
|
+
const { dsl, DslBuilder } = require('schema-dsl');
|
|
373
|
+
|
|
347
374
|
const schema = dsl({
|
|
348
375
|
level1: {
|
|
349
376
|
level2: {
|
|
@@ -354,15 +381,15 @@ const schema = dsl({
|
|
|
354
381
|
}
|
|
355
382
|
});
|
|
356
383
|
|
|
357
|
-
const
|
|
358
|
-
// 返回: 4
|
|
384
|
+
const result = DslBuilder.validateNestingDepth(schema, 10);
|
|
385
|
+
// 返回: { valid: true, depth: 4, path: 'level1.level2.level3', message: '...' }
|
|
359
386
|
|
|
360
|
-
if (depth > 5) {
|
|
387
|
+
if (result.depth > 5) {
|
|
361
388
|
console.warn('嵌套层级过深,建议扁平化');
|
|
362
389
|
}
|
|
363
390
|
```
|
|
364
391
|
|
|
365
|
-
|
|
392
|
+
**说明**: 这个能力属于 `DslBuilder` 静态方法,不是 `SchemaUtils` 的成员;这里一并列出是因为它常与 Schema 工具链一起使用。
|
|
366
393
|
|
|
367
394
|
---
|
|
368
395
|
|
|
@@ -485,6 +512,13 @@ const schema = dsl({
|
|
|
485
512
|
|
|
486
513
|
---
|
|
487
514
|
|
|
488
|
-
|
|
515
|
+
## 对应示例文件
|
|
516
|
+
|
|
517
|
+
**示例入口**: [schema-utils.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/schema-utils.ts)
|
|
518
|
+
**说明**: 覆盖 `reusable()`、`createLibrary()`、`extend()`、`validateBatch()`、`withPerformance()` 和 `clone()` 的最小工作流。
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
**最后更新**: 2026-05-08
|
|
489
523
|
|
|
490
524
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 安全检查清单
|
|
2
|
+
|
|
3
|
+
## 发布前检查
|
|
4
|
+
|
|
5
|
+
- 运行 `npm audit --audit-level=moderate`。
|
|
6
|
+
- 确认文档示例不包含真实密钥、Token 或密码。
|
|
7
|
+
- 自定义正则应避免灾难性回溯。
|
|
8
|
+
- 自定义 validator 不应执行不可信输入生成的代码。
|
|
9
|
+
|
|
10
|
+
## 当前建议
|
|
11
|
+
|
|
12
|
+
依赖升级后应重新运行完整测试与构建验证。
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 对应示例文件
|
|
17
|
+
|
|
18
|
+
**示例入口**: [security-checklist.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/security-checklist.ts)
|
|
19
|
+
**说明**: 使用占位 token、受限字符集和显式 URL 校验,示范文档中“不要暴露真实凭据”“正则要有界”的落地写法。
|
|
20
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# String 扩展文档
|
|
2
2
|
|
|
3
|
-
> **更新时间**:
|
|
3
|
+
> **更新时间**: 2026-05-22
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -63,7 +63,7 @@ const schema = dsl({
|
|
|
63
63
|
| `.label(text)` | 字段标签 | `'email!'.label('邮箱地址')` |
|
|
64
64
|
| `.messages(obj)` | 自定义消息 | `'string!'.messages({...})` |
|
|
65
65
|
| `.description(text)` | 描述 | `'url'.description('主页')` |
|
|
66
|
-
| `.custom(fn)` |
|
|
66
|
+
| `.custom(fn)` | 自定义同步验证 | `'string!'.custom(value => value !== "admin")` |
|
|
67
67
|
| `.default(value)` | 默认值 | `'string'.default('guest')` |
|
|
68
68
|
| `.username(range?)` | 用户名验证 | `'string!'.username('5-20')` |
|
|
69
69
|
| `.phone(country)` | 手机号验证 | `'string!'.phone('cn')` |
|
|
@@ -179,9 +179,8 @@ const schema = dsl({
|
|
|
179
179
|
const schema = dsl({
|
|
180
180
|
// 最优雅:只在失败时返回错误消息
|
|
181
181
|
username: 'string:3-32!'
|
|
182
|
-
.custom(
|
|
183
|
-
|
|
184
|
-
if (exists) return '用户名已被占用';
|
|
182
|
+
.custom((value) => {
|
|
183
|
+
if (value === 'admin') return '用户名已被占用';
|
|
185
184
|
// 成功时无需返回
|
|
186
185
|
})
|
|
187
186
|
.label('用户名'),
|
|
@@ -197,6 +196,8 @@ const schema = dsl({
|
|
|
197
196
|
});
|
|
198
197
|
```
|
|
199
198
|
|
|
199
|
+
⚠️ `.custom()` 当前仅支持同步函数;需要异步查库或远程调用时,请在 `validate()` / `validateAsync()` 通过后于业务层单独执行。
|
|
200
|
+
|
|
200
201
|
**支持的返回值**:
|
|
201
202
|
- 不返回/`undefined` → 验证通过 ✅
|
|
202
203
|
- 返回字符串 → 验证失败(错误消息)
|
|
@@ -206,8 +207,8 @@ const schema = dsl({
|
|
|
206
207
|
- 返回 `false` → 验证失败(默认消息)
|
|
207
208
|
|
|
208
209
|
**注意**:
|
|
209
|
-
-
|
|
210
|
-
-
|
|
210
|
+
- 当前版本**不支持**在 `.custom()` 中直接返回 `Promise`;即使调用 `validateAsync()`,异步 custom validator 仍会报 `同步验证不支持异步操作`。
|
|
211
|
+
- 需要异步校验时,请改为:① 先用 `schema-dsl` 做同步结构校验;② 再在业务层执行异步检查。
|
|
211
212
|
|
|
212
213
|
|
|
213
214
|
---
|
|
@@ -471,10 +472,17 @@ const schema = dsl({
|
|
|
471
472
|
- [DSL 语法](./dsl-syntax.md)
|
|
472
473
|
- [API 参考](./api-reference.md)
|
|
473
474
|
- [多语言支持](./multi-language.md)
|
|
474
|
-
- [示例代码](
|
|
475
|
+
- [示例代码](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/string-extensions.ts)
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## 对应示例文件
|
|
480
|
+
|
|
481
|
+
**示例入口**: [string-extensions.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/string-extensions.ts)
|
|
482
|
+
**说明**: 覆盖 String.prototype 扩展的安装/卸载、链式 `.label()` / `.messages()` / `.pattern()` 调用,以及校验成功/失败路径。
|
|
475
483
|
|
|
476
484
|
---
|
|
477
485
|
|
|
478
|
-
**最后更新**:
|
|
486
|
+
**最后更新**: 2026-05-08
|
|
479
487
|
|
|
480
488
|
|
package/docs/troubleshooting.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 常见问题排查指南
|
|
2
2
|
|
|
3
|
-
> **用途**: 快速解决
|
|
3
|
+
> **用途**: 快速解决 schema-dsl 使用中的常见问题
|
|
4
4
|
> **更新**: 2025-12-26
|
|
5
5
|
|
|
6
6
|
---
|
|
@@ -41,10 +41,10 @@ const validator = new Validator({ verbose: true });
|
|
|
41
41
|
const result = validator.validate(schema, data);
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
3. **使用 Schema
|
|
44
|
+
3. **使用 Schema 摘要工具**
|
|
45
45
|
```javascript
|
|
46
|
-
const {
|
|
47
|
-
console.log(
|
|
46
|
+
const { SchemaHelper } = require('schema-dsl');
|
|
47
|
+
console.log(SchemaHelper.summarizeSchema(schema));
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
4. **检查字段名是否正确**
|
|
@@ -79,14 +79,20 @@ email: 'email!'.custom(async (value) => {
|
|
|
79
79
|
// ❌ 错误:在 validate() 中使用异步验证器
|
|
80
80
|
const result = validate(schema, data); // 同步模式
|
|
81
81
|
|
|
82
|
-
//
|
|
83
|
-
|
|
82
|
+
// ❌ 误区:validateAsync() 也不会让 .custom(async fn) 生效
|
|
83
|
+
await validateAsync(schema, data); // 仍会抛“同步验证不支持异步操作”
|
|
84
84
|
|
|
85
|
-
// ✅
|
|
85
|
+
// ✅ 正确:使用同步验证器
|
|
86
86
|
email: 'email!'.custom((value) => {
|
|
87
87
|
// 同步代码
|
|
88
88
|
if (checkSync(value)) return '邮箱已被占用';
|
|
89
89
|
})
|
|
90
|
+
|
|
91
|
+
// ✅ 或者:把异步检查放到 schema-dsl 之外
|
|
92
|
+
const result = validate(schema, data);
|
|
93
|
+
if (result.valid) {
|
|
94
|
+
await checkEmailUniqueness(data.email);
|
|
95
|
+
}
|
|
90
96
|
```
|
|
91
97
|
|
|
92
98
|
#### 原因2: custom() 返回值不正确
|
|
@@ -258,13 +264,15 @@ console.log(Object.keys(Locale.locales));
|
|
|
258
264
|
// 应该包含: ['zh-CN', 'en-US', 'ja-JP', ...]
|
|
259
265
|
```
|
|
260
266
|
|
|
261
|
-
#### 2.
|
|
267
|
+
#### 2. 检查验证调用是否传入 locale
|
|
262
268
|
```javascript
|
|
263
|
-
// ❌
|
|
269
|
+
// ❌ 构造函数不会设置本次验证语言
|
|
264
270
|
const validator = new Validator();
|
|
265
271
|
|
|
266
|
-
// ✅
|
|
267
|
-
const
|
|
272
|
+
// ✅ 在 validate 时按次指定语言
|
|
273
|
+
const result = validator.validate(schema, data, {
|
|
274
|
+
locale: 'zh-CN'
|
|
275
|
+
});
|
|
268
276
|
```
|
|
269
277
|
|
|
270
278
|
#### 3. 动态切换语言
|
|
@@ -378,7 +386,7 @@ db.createCollection('users', {
|
|
|
378
386
|
|
|
379
387
|
**解决方案**:
|
|
380
388
|
```javascript
|
|
381
|
-
//
|
|
389
|
+
// schema-dsl 默认会自动安装 String 扩展
|
|
382
390
|
// 如果未生效,手动安装:
|
|
383
391
|
const { installStringExtensions } = require('schema-dsl');
|
|
384
392
|
installStringExtensions();
|
|
@@ -405,15 +413,15 @@ console.log(JSON.stringify(schema, null, 2));
|
|
|
405
413
|
// 查看实际生成的 JSON Schema 结构
|
|
406
414
|
```
|
|
407
415
|
|
|
408
|
-
### 技巧2: 使用 Schema
|
|
416
|
+
### 技巧2: 使用 Schema 摘要工具
|
|
409
417
|
|
|
410
418
|
```javascript
|
|
411
|
-
const {
|
|
419
|
+
const { SchemaHelper } = require('schema-dsl');
|
|
412
420
|
|
|
413
|
-
//
|
|
414
|
-
const
|
|
415
|
-
console.log(
|
|
416
|
-
//
|
|
421
|
+
// 查看 Schema 结构摘要
|
|
422
|
+
const summary = SchemaHelper.summarizeSchema(schema);
|
|
423
|
+
console.log(summary);
|
|
424
|
+
// 输出字段列表、required 数量、复杂度等
|
|
417
425
|
```
|
|
418
426
|
|
|
419
427
|
### 技巧3: 启用详细日志
|
|
@@ -458,13 +466,20 @@ describe('User Schema', () => {
|
|
|
458
466
|
|
|
459
467
|
如果以上方法无法解决你的问题:
|
|
460
468
|
|
|
461
|
-
1. **查看文档**: [完整文档索引](
|
|
462
|
-
2. **查看示例**: [
|
|
463
|
-
3. **GitHub Issues**: [提交问题](https://github.com/
|
|
469
|
+
1. **查看文档**: [完整文档索引](doc-index.md)
|
|
470
|
+
2. **查看示例**: [troubleshooting.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/troubleshooting.ts)
|
|
471
|
+
3. **GitHub Issues**: [提交问题](https://github.com/vextjs/schema-dsl/issues)
|
|
464
472
|
4. **常见问题**: [FAQ.md](faq.md)
|
|
465
473
|
|
|
466
474
|
---
|
|
467
475
|
|
|
476
|
+
## 对应示例文件
|
|
477
|
+
|
|
478
|
+
**示例入口**: [troubleshooting.ts](https://github.com/vextjs/schema-dsl/blob/main/examples/docs/troubleshooting.ts)
|
|
479
|
+
**说明**: 演示如何用 `validate()` 和 `compile()` 复现错误、查看路径/关键字/消息,并快速定位失败原因。
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
468
483
|
## 贡献
|
|
469
484
|
|
|
470
485
|
发现了新的常见问题?欢迎提交 PR 补充本文档!
|