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.
Files changed (109) hide show
  1. package/.eslintignore +10 -0
  2. package/.eslintrc.json +27 -0
  3. package/.github/CODE_OF_CONDUCT.md +45 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +57 -0
  5. package/.github/ISSUE_TEMPLATE/config.yml +11 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +45 -0
  7. package/.github/ISSUE_TEMPLATE/question.md +31 -0
  8. package/.github/PULL_REQUEST_TEMPLATE.md +70 -0
  9. package/.github/SECURITY.md +184 -0
  10. package/.github/workflows/ci.yml +35 -0
  11. package/CHANGELOG.md +633 -0
  12. package/CONTRIBUTING.md +368 -0
  13. package/LICENSE +21 -0
  14. package/README.md +1122 -0
  15. package/STATUS.md +273 -0
  16. package/docs/FEATURE-INDEX.md +521 -0
  17. package/docs/INDEX.md +224 -0
  18. package/docs/api-reference.md +1098 -0
  19. package/docs/best-practices.md +672 -0
  20. package/docs/cache-manager.md +336 -0
  21. package/docs/design-philosophy.md +602 -0
  22. package/docs/dsl-syntax.md +654 -0
  23. package/docs/dynamic-locale.md +552 -0
  24. package/docs/error-handling.md +703 -0
  25. package/docs/export-guide.md +459 -0
  26. package/docs/faq.md +576 -0
  27. package/docs/frontend-i18n-guide.md +290 -0
  28. package/docs/i18n-user-guide.md +488 -0
  29. package/docs/label-vs-description.md +262 -0
  30. package/docs/markdown-exporter.md +398 -0
  31. package/docs/mongodb-exporter.md +279 -0
  32. package/docs/multi-type-support.md +319 -0
  33. package/docs/mysql-exporter.md +257 -0
  34. package/docs/plugin-system.md +542 -0
  35. package/docs/postgresql-exporter.md +290 -0
  36. package/docs/quick-start.md +761 -0
  37. package/docs/schema-helper.md +340 -0
  38. package/docs/schema-utils.md +492 -0
  39. package/docs/string-extensions.md +480 -0
  40. package/docs/troubleshooting.md +471 -0
  41. package/docs/type-converter.md +319 -0
  42. package/docs/type-reference.md +219 -0
  43. package/docs/validate.md +486 -0
  44. package/docs/validation-guide.md +484 -0
  45. package/examples/array-dsl-example.js +227 -0
  46. package/examples/custom-extension.js +85 -0
  47. package/examples/dsl-match-example.js +74 -0
  48. package/examples/dsl-style.js +118 -0
  49. package/examples/dynamic-locale-configuration.js +348 -0
  50. package/examples/dynamic-locale-example.js +287 -0
  51. package/examples/export-demo.js +130 -0
  52. package/examples/i18n-full-demo.js +310 -0
  53. package/examples/i18n-memory-safety.examples.js +268 -0
  54. package/examples/markdown-export.js +71 -0
  55. package/examples/middleware-usage.js +93 -0
  56. package/examples/password-reset/README.md +153 -0
  57. package/examples/password-reset/schema.js +26 -0
  58. package/examples/password-reset/test.js +101 -0
  59. package/examples/plugin-system.examples.js +205 -0
  60. package/examples/simple-example.js +122 -0
  61. package/examples/string-extensions.js +297 -0
  62. package/examples/user-registration/README.md +156 -0
  63. package/examples/user-registration/routes.js +92 -0
  64. package/examples/user-registration/schema.js +150 -0
  65. package/examples/user-registration/server.js +74 -0
  66. package/index.d.ts +1999 -0
  67. package/index.js +270 -0
  68. package/index.mjs +30 -0
  69. package/lib/adapters/DslAdapter.js +653 -0
  70. package/lib/adapters/index.js +20 -0
  71. package/lib/config/constants.js +286 -0
  72. package/lib/config/patterns/creditCard.js +9 -0
  73. package/lib/config/patterns/idCard.js +9 -0
  74. package/lib/config/patterns/index.js +8 -0
  75. package/lib/config/patterns/licensePlate.js +4 -0
  76. package/lib/config/patterns/passport.js +4 -0
  77. package/lib/config/patterns/phone.js +9 -0
  78. package/lib/config/patterns/postalCode.js +5 -0
  79. package/lib/core/CacheManager.js +376 -0
  80. package/lib/core/DslBuilder.js +740 -0
  81. package/lib/core/ErrorCodes.js +233 -0
  82. package/lib/core/ErrorFormatter.js +342 -0
  83. package/lib/core/JSONSchemaCore.js +347 -0
  84. package/lib/core/Locale.js +119 -0
  85. package/lib/core/MessageTemplate.js +89 -0
  86. package/lib/core/PluginManager.js +448 -0
  87. package/lib/core/StringExtensions.js +209 -0
  88. package/lib/core/Validator.js +316 -0
  89. package/lib/exporters/MarkdownExporter.js +420 -0
  90. package/lib/exporters/MongoDBExporter.js +162 -0
  91. package/lib/exporters/MySQLExporter.js +212 -0
  92. package/lib/exporters/PostgreSQLExporter.js +289 -0
  93. package/lib/exporters/index.js +24 -0
  94. package/lib/locales/en-US.js +65 -0
  95. package/lib/locales/es-ES.js +66 -0
  96. package/lib/locales/fr-FR.js +66 -0
  97. package/lib/locales/index.js +8 -0
  98. package/lib/locales/ja-JP.js +66 -0
  99. package/lib/locales/zh-CN.js +93 -0
  100. package/lib/utils/LRUCache.js +174 -0
  101. package/lib/utils/SchemaHelper.js +240 -0
  102. package/lib/utils/SchemaUtils.js +313 -0
  103. package/lib/utils/TypeConverter.js +245 -0
  104. package/lib/utils/index.js +13 -0
  105. package/lib/validators/CustomKeywords.js +203 -0
  106. package/lib/validators/index.js +11 -0
  107. package/package.json +70 -0
  108. package/plugins/custom-format.js +101 -0
  109. package/plugins/custom-validator.js +200 -0
package/index.js ADDED
@@ -0,0 +1,270 @@
1
+ /**
2
+ * SchemaIO 2.0 - 主入口文件
3
+ *
4
+ * 统一的DSL Builder Pattern
5
+ * 简洁 + 强大 = 完美平衡
6
+ *
7
+ * @module schema-dsl
8
+ * @version 2.0.0
9
+ */
10
+
11
+ // ========== 核心层 ==========
12
+ const JSONSchemaCore = require('./lib/core/JSONSchemaCore');
13
+ const Validator = require('./lib/core/Validator');
14
+ const ErrorFormatter = require('./lib/core/ErrorFormatter');
15
+ const CacheManager = require('./lib/core/CacheManager');
16
+ const DslBuilder = require('./lib/core/DslBuilder');
17
+ const PluginManager = require('./lib/core/PluginManager');
18
+
19
+ // ========== 错误消息系统 ==========
20
+ const ErrorCodes = require('./lib/core/ErrorCodes');
21
+ const MessageTemplate = require('./lib/core/MessageTemplate');
22
+ const Locale = require('./lib/core/Locale');
23
+
24
+ // ========== String 扩展 ==========
25
+ const { installStringExtensions, uninstallStringExtensions } = require('./lib/core/StringExtensions');
26
+
27
+ // ========== 适配器层 ==========
28
+ const dsl = require('./lib/adapters/DslAdapter');
29
+
30
+ // 挂载静态方法 (v2.1.0)
31
+ dsl.match = dsl.DslAdapter.match;
32
+ dsl.if = dsl.DslAdapter.if;
33
+
34
+ /**
35
+ * 全局配置
36
+ * @param {Object} options - 配置选项
37
+ * @param {Object} options.patterns - 验证规则扩展 (phone, idCard, creditCard)
38
+ * @param {Object} options.phone - 手机号验证规则扩展 (兼容旧版)
39
+ */
40
+ dsl.config = function (options = {}) {
41
+ const patterns = require('./lib/config/patterns');
42
+
43
+ // 兼容旧版 options.phone
44
+ if (options.phone) {
45
+ Object.assign(patterns.phone, options.phone);
46
+ }
47
+
48
+ // 新版 options.patterns
49
+ if (options.patterns) {
50
+ if (options.patterns.phone) Object.assign(patterns.phone, options.patterns.phone);
51
+ if (options.patterns.idCard) Object.assign(patterns.idCard, options.patterns.idCard);
52
+ if (options.patterns.creditCard) Object.assign(patterns.creditCard, options.patterns.creditCard);
53
+ }
54
+
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);
78
+ }
79
+ }
80
+ }
81
+ };
82
+
83
+ // ========== 导出器层 ==========
84
+ const exporters = require('./lib/exporters');
85
+
86
+ // ========== 初始化默认语言包 ==========
87
+ const defaultLocales = require('./lib/locales');
88
+ Object.entries(defaultLocales).forEach(([locale, messages]) => {
89
+ Locale.addLocale(locale, messages);
90
+ });
91
+
92
+ // ========== 单例Validator ==========
93
+ let _defaultValidator = null;
94
+
95
+ /**
96
+ * 获取默认Validator实例(单例)
97
+ * @returns {Validator}
98
+ */
99
+ function getDefaultValidator() {
100
+ if (!_defaultValidator) {
101
+ _defaultValidator = new Validator();
102
+ }
103
+ return _defaultValidator;
104
+ }
105
+
106
+ /**
107
+ * 便捷验证方法(使用默认Validator)
108
+ * @param {Object} schema - JSON Schema对象
109
+ * @param {*} data - 待验证数据
110
+ * @returns {Object} 验证结果
111
+ *
112
+ * @example
113
+ * const { validate, dsl } = require('schema-dsl');
114
+ *
115
+ * const schema = dsl({ email: 'email!' });
116
+ * const result = validate(schema, { email: 'test@example.com' });
117
+ */
118
+ function validate(schema, data) {
119
+ return getDefaultValidator().validate(schema, data);
120
+ }
121
+
122
+ // ========== 工具函数 ==========
123
+ const { TypeConverter, SchemaHelper } = require('./lib/utils');
124
+ const SchemaUtils = require('./lib/utils/SchemaUtils');
125
+
126
+ // ========== 验证器扩展 ==========
127
+ const { CustomKeywords } = require('./lib/validators');
128
+
129
+ // ========== 常量 ==========
130
+ const CONSTANTS = require('./lib/config/constants');
131
+
132
+ // ========== 自动安装 String 扩展 ==========
133
+ installStringExtensions(dsl);
134
+
135
+ // ========== 全局配置函数 ==========
136
+ /**
137
+ * 全局配置
138
+ * @param {Object} options - 配置选项
139
+ * @param {Object} options.i18n - 多语言配置
140
+ * @param {string} options.i18n.localesPath - 用户语言包目录路径
141
+ * @param {Object} options.i18n.locales - 直接传入的语言包对象
142
+ * @param {Object} options.cache - 缓存配置
143
+ * @param {number} options.cache.maxSize - 缓存最大条目数
144
+ * @param {number} options.cache.ttl - 缓存过期时间(ms)
145
+ *
146
+ * @example
147
+ * dsl.config({
148
+ * i18n: {
149
+ * localesPath: './i18n/labels'
150
+ * },
151
+ * cache: {
152
+ * maxSize: 10000,
153
+ * ttl: 7200000
154
+ * }
155
+ * });
156
+ */
157
+ dsl.config = function(options = {}) {
158
+ // ========== 用户语言包配置 ==========
159
+ if (options.i18n) {
160
+ const { localesPath, locales } = options.i18n;
161
+
162
+ // 方式 1:从路径加载语言包文件
163
+ if (localesPath) {
164
+ const fs = require('fs');
165
+ const path = require('path');
166
+
167
+ const resolvedPath = path.resolve(localesPath);
168
+
169
+ if (fs.existsSync(resolvedPath)) {
170
+ const files = fs.readdirSync(resolvedPath);
171
+
172
+ files.forEach(file => {
173
+ if (file.endsWith('.js') || file.endsWith('.json')) {
174
+ const locale = path.basename(file, path.extname(file));
175
+ try {
176
+ const messages = require(path.join(resolvedPath, file));
177
+ Locale.addLocale(locale, messages);
178
+ if (process.env.DEBUG) {
179
+ console.log(`[schema-dsl] Loaded user locale: ${locale}`);
180
+ }
181
+ } catch (error) {
182
+ console.warn(`[schema-dsl] Failed to load locale ${locale}:`, error.message);
183
+ }
184
+ }
185
+ });
186
+ } else {
187
+ console.warn(`[schema-dsl] Locales path not found: ${resolvedPath}`);
188
+ }
189
+ }
190
+
191
+ // 方式 2:直接传入语言包对象
192
+ if (locales && typeof locales === 'object') {
193
+ Object.keys(locales).forEach(locale => {
194
+ Locale.addLocale(locale, locales[locale]);
195
+ if (process.env.DEBUG) {
196
+ console.log(`[schema-dsl] Added user locale: ${locale}`);
197
+ }
198
+ });
199
+ }
200
+ }
201
+
202
+ // ========== 缓存配置 ==========
203
+ if (options.cache) {
204
+ const { maxSize, ttl } = options.cache;
205
+
206
+ // 更新默认 Validator 的缓存配置
207
+ if (_defaultValidator) {
208
+ if (maxSize !== undefined) {
209
+ _defaultValidator.cache.options.maxSize = maxSize;
210
+ }
211
+ if (ttl !== undefined) {
212
+ _defaultValidator.cache.options.ttl = ttl;
213
+ }
214
+ if (process.env.DEBUG) {
215
+ console.log(`[schema-dsl] Updated cache config: maxSize=${maxSize || 'default'}, ttl=${ttl || 'default'}ms`);
216
+ }
217
+ }
218
+ }
219
+ };
220
+
221
+ // ========== 导出 ==========
222
+
223
+ module.exports = {
224
+ // 统一DSL API
225
+ dsl,
226
+ DslBuilder,
227
+
228
+ // String 扩展控制
229
+ installStringExtensions: () => installStringExtensions(dsl),
230
+ uninstallStringExtensions,
231
+
232
+ // 核心类
233
+ JSONSchemaCore,
234
+ Validator,
235
+
236
+ // 便捷方法(推荐)
237
+ validate, // 便捷验证(单例)
238
+ getDefaultValidator, // 获取单例Validator
239
+ ErrorFormatter,
240
+ CacheManager,
241
+
242
+ // 错误消息系统
243
+ ErrorCodes,
244
+ MessageTemplate,
245
+ Locale,
246
+
247
+ // 插件系统 (v2.2.0 新增)
248
+ PluginManager,
249
+
250
+ // 导出器
251
+ exporters,
252
+ MongoDBExporter: exporters.MongoDBExporter,
253
+ MySQLExporter: exporters.MySQLExporter,
254
+ PostgreSQLExporter: exporters.PostgreSQLExporter,
255
+ MarkdownExporter: exporters.MarkdownExporter,
256
+
257
+ // 工具函数
258
+ TypeConverter,
259
+ SchemaHelper,
260
+ SchemaUtils, // v2.0.1新增:Schema工具类
261
+
262
+ // 验证器扩展
263
+ CustomKeywords,
264
+
265
+ // 常量
266
+ CONSTANTS,
267
+
268
+ // 版本信息
269
+ VERSION: '2.3.0'
270
+ };
package/index.mjs ADDED
@@ -0,0 +1,30 @@
1
+ import schema-dsl from './index.js';
2
+
3
+ export const {
4
+ dsl,
5
+ validate,
6
+ getDefaultValidator,
7
+ JSONSchemaCore,
8
+ Validator,
9
+ ErrorFormatter,
10
+ CacheManager,
11
+ DslBuilder,
12
+ ErrorCodes,
13
+ MessageTemplate,
14
+ Locale,
15
+ exporters,
16
+ MongoDBExporter,
17
+ MySQLExporter,
18
+ PostgreSQLExporter,
19
+ TypeConverter,
20
+ SchemaHelper,
21
+ SchemaUtils,
22
+ CustomKeywords,
23
+ CONSTANTS,
24
+ VERSION,
25
+ installStringExtensions,
26
+ uninstallStringExtensions
27
+ } = schema-dsl;
28
+
29
+ export default schema-dsl;
30
+