schema-dsl 1.0.0 → 1.0.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +263 -529
  2. package/README.md +814 -896
  3. package/STATUS.md +135 -2
  4. package/docs/INDEX.md +1 -2
  5. package/docs/api-reference.md +1 -292
  6. package/docs/custom-extensions-guide.md +411 -0
  7. package/docs/enum.md +475 -0
  8. package/docs/i18n.md +394 -0
  9. package/docs/performance-benchmark-report.md +179 -0
  10. package/docs/plugin-system.md +8 -8
  11. package/docs/typescript-guide.md +554 -0
  12. package/docs/validate-async.md +1 -1
  13. package/docs/validation-rules-v1.0.2.md +1601 -0
  14. package/examples/README.md +81 -0
  15. package/examples/enum.examples.js +324 -0
  16. package/examples/express-integration.js +54 -54
  17. package/examples/i18n-full-demo.js +15 -24
  18. package/examples/schema-utils-chaining.examples.js +2 -2
  19. package/examples/slug.examples.js +179 -0
  20. package/index.d.ts +246 -17
  21. package/index.js +30 -34
  22. package/lib/config/constants.js +1 -1
  23. package/lib/config/patterns/common.js +47 -0
  24. package/lib/config/patterns/index.js +2 -1
  25. package/lib/core/DslBuilder.js +500 -8
  26. package/lib/core/StringExtensions.js +31 -0
  27. package/lib/core/Validator.js +42 -15
  28. package/lib/errors/ValidationError.js +3 -3
  29. package/lib/locales/en-US.js +79 -19
  30. package/lib/locales/es-ES.js +60 -19
  31. package/lib/locales/fr-FR.js +84 -43
  32. package/lib/locales/ja-JP.js +83 -42
  33. package/lib/locales/zh-CN.js +32 -0
  34. package/lib/validators/CustomKeywords.js +405 -0
  35. package/package.json +1 -1
  36. package/.github/CODE_OF_CONDUCT.md +0 -45
  37. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -57
  38. package/.github/ISSUE_TEMPLATE/config.yml +0 -11
  39. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -45
  40. package/.github/ISSUE_TEMPLATE/question.md +0 -31
  41. package/.github/PULL_REQUEST_TEMPLATE.md +0 -70
  42. package/.github/SECURITY.md +0 -184
  43. package/.github/workflows/ci.yml +0 -33
  44. package/plugins/custom-format.js +0 -101
  45. package/plugins/custom-validator.js +0 -200
package/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * SchemaIO 2.0 - 主入口文件
2
+ * schema-dsl - 主入口文件
3
3
  *
4
4
  * 统一的DSL Builder Pattern
5
5
  * 简洁 + 强大 = 完美平衡
6
6
  *
7
7
  * @module schema-dsl
8
- * @version 2.0.0
8
+ * @version 1.0.3
9
9
  */
10
10
 
11
11
  // ========== 核心层 ==========
@@ -35,48 +35,44 @@ dsl.if = dsl.DslAdapter.if;
35
35
  * 全局配置
36
36
  * @param {Object} options - 配置选项
37
37
  * @param {Object} options.patterns - 验证规则扩展 (phone, idCard, creditCard)
38
- * @param {Object} options.phone - 手机号验证规则扩展 (兼容旧版)
38
+ * @param {string|Object} options.i18n - 多语言配置(目录路径或语言包对象)
39
39
  */
40
40
  dsl.config = function (options = {}) {
41
41
  const patterns = require('./lib/config/patterns');
42
42
 
43
- // 兼容旧版 options.phone
44
- if (options.phone) {
45
- Object.assign(patterns.phone, options.phone);
46
- }
47
-
48
- // 新版 options.patterns
43
+ // patterns 配置
49
44
  if (options.patterns) {
50
45
  if (options.patterns.phone) Object.assign(patterns.phone, options.patterns.phone);
51
46
  if (options.patterns.idCard) Object.assign(patterns.idCard, options.patterns.idCard);
52
47
  if (options.patterns.creditCard) Object.assign(patterns.creditCard, options.patterns.creditCard);
53
48
  }
54
49
 
55
- // 多语言支持 (v2.1.0)
56
- if (options.locales) {
57
- if (typeof options.locales === 'object') {
58
- Object.keys(options.locales).forEach(locale => {
59
- Locale.addLocale(locale, options.locales[locale]);
60
- });
61
- } else if (typeof options.locales === 'string') {
62
- // 支持传入目录路径
63
- try {
64
- const fs = require('fs');
65
- const path = require('path');
66
- if (fs.existsSync(options.locales) && fs.statSync(options.locales).isDirectory()) {
67
- const files = fs.readdirSync(options.locales);
68
- files.forEach(file => {
69
- if (file.endsWith('.js') || file.endsWith('.json')) {
70
- const localeName = path.basename(file, path.extname(file));
71
- const messages = require(path.resolve(options.locales, file));
72
- Locale.addLocale(localeName, messages);
73
- }
74
- });
75
- }
76
- } catch (e) {
77
- console.warn('[SchemaIO] Failed to load locales from path:', e.message);
50
+ // 多语言支持 (v1.0.1 优化)
51
+ if (options.i18n) {
52
+ // 方式 1: 传入目录路径(字符串)
53
+ if (typeof options.i18n === 'string') {
54
+ const fs = require('fs');
55
+ const path = require('path');
56
+
57
+ if (fs.existsSync(options.i18n) && fs.statSync(options.i18n).isDirectory()) {
58
+ const files = fs.readdirSync(options.i18n);
59
+ files.forEach(file => {
60
+ if (file.endsWith('.js') || file.endsWith('.json')) {
61
+ const localeName = path.basename(file, path.extname(file));
62
+ const messages = require(path.resolve(options.i18n, file));
63
+ Locale.addLocale(localeName, messages);
64
+ }
65
+ });
66
+ } else {
67
+ console.warn('[schema-dsl] i18n path does not exist:', options.i18n);
78
68
  }
79
69
  }
70
+ // 方式 2: 直接传入对象
71
+ else if (typeof options.i18n === 'object') {
72
+ Object.keys(options.i18n).forEach(locale => {
73
+ Locale.addLocale(locale, options.i18n[locale]);
74
+ });
75
+ }
80
76
  }
81
77
  };
82
78
 
@@ -154,7 +150,7 @@ installStringExtensions(dsl);
154
150
  * }
155
151
  * });
156
152
  */
157
- dsl.config = function(options = {}) {
153
+ dsl.config = function (options = {}) {
158
154
  // ========== 用户语言包配置 ==========
159
155
  if (options.i18n) {
160
156
  const { localesPath, locales } = options.i18n;
@@ -276,7 +272,7 @@ module.exports = {
276
272
  CONSTANTS,
277
273
 
278
274
  // 版本信息
279
- VERSION: '2.1.0'
275
+ VERSION: '1.0.3'
280
276
  };
281
277
 
282
278
 
@@ -236,7 +236,7 @@ module.exports = {
236
236
  DEFAULT_STYLE: 'joi',
237
237
 
238
238
  // API版本
239
- VERSION: '2.0.0'
239
+ VERSION: '1.0.3'
240
240
  },
241
241
 
242
242
  // ========== 插件配置 ==========
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 通用验证模式(v1.0.2新增)
3
+ *
4
+ * @module lib/config/patterns/common
5
+ */
6
+
7
+ module.exports = {
8
+ /**
9
+ * 域名验证
10
+ * 支持格式: example.com, sub.example.com
11
+ */
12
+ domain: {
13
+ pattern: /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$/i,
14
+ key: 'pattern.domain',
15
+ min: 3,
16
+ max: 253
17
+ },
18
+
19
+ /**
20
+ * IP地址验证(IPv4 或 IPv6)
21
+ * 支持格式: 192.168.1.1, 2001:0db8:85a3::8a2e:0370:7334
22
+ */
23
+ ip: {
24
+ // 同时支持IPv4和IPv6的复合正则
25
+ pattern: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$|^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
26
+ key: 'pattern.ip'
27
+ },
28
+
29
+ /**
30
+ * Base64编码验证
31
+ * 支持标准Base64格式(带或不带padding)
32
+ */
33
+ base64: {
34
+ pattern: /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,
35
+ key: 'pattern.base64'
36
+ },
37
+
38
+ /**
39
+ * JWT令牌验证
40
+ * 支持格式: header.payload.signature
41
+ */
42
+ jwt: {
43
+ pattern: /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,
44
+ key: 'pattern.jwt'
45
+ }
46
+ };
47
+
@@ -4,5 +4,6 @@ module.exports = {
4
4
  creditCard: require('./creditCard'),
5
5
  licensePlate: require('./licensePlate'),
6
6
  postalCode: require('./postalCode'),
7
- passport: require('./passport')
7
+ passport: require('./passport'),
8
+ common: require('./common') // v1.0.2新增
8
9
  };