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
@@ -0,0 +1,313 @@
1
+ /**
2
+ * Schema工具类 v2.0.1
3
+ *
4
+ * 提供Schema复用、合并、性能监控等功能
5
+ */
6
+
7
+ class SchemaUtils {
8
+ // ========== Schema复用 ==========
9
+
10
+ /**
11
+ * 创建可复用的Schema片段
12
+ * @param {Function} factory - Schema工厂函数
13
+ * @returns {Function} 返回工厂函数
14
+ *
15
+ * @example
16
+ * const emailField = SchemaUtils.reusable(() =>
17
+ * 'email!'.pattern(/custom/).label('邮箱')
18
+ * );
19
+ *
20
+ * const schema1 = dsl({ email: emailField() });
21
+ * const schema2 = dsl({ contactEmail: emailField() });
22
+ */
23
+ static reusable(factory) {
24
+ return factory;
25
+ }
26
+
27
+ /**
28
+ * 创建Schema片段库
29
+ * @param {Object} fragments - Schema片段对象
30
+ * @returns {Object} 片段库
31
+ *
32
+ * @example
33
+ * const fields = SchemaUtils.createLibrary({
34
+ * email: () => 'email!'.label('邮箱'),
35
+ * phone: () => 'string:11!'.phoneNumber('cn').label('手机号'),
36
+ * username: () => 'string:3-32!'.username().label('用户名')
37
+ * });
38
+ *
39
+ * const schema = dsl({
40
+ * email: fields.email(),
41
+ * phone: fields.phone()
42
+ * });
43
+ */
44
+ static createLibrary(fragments) {
45
+ return fragments;
46
+ }
47
+
48
+ // ========== Schema合并 ==========
49
+
50
+ /**
51
+ * 合并多个Schema
52
+ * @param {...Object} schemas - 要合并的Schema对象
53
+ * @returns {Object} 合并后的Schema
54
+ *
55
+ * @example
56
+ * const baseUser = dsl({ name: 'string!', email: 'email!' });
57
+ * const withAge = dsl({ age: 'number:18-120' });
58
+ * const merged = SchemaUtils.merge(baseUser, withAge);
59
+ */
60
+ static merge(...schemas) {
61
+ const result = {
62
+ type: 'object',
63
+ properties: {},
64
+ required: []
65
+ };
66
+
67
+ schemas.forEach(schema => {
68
+ if (schema.properties) {
69
+ Object.assign(result.properties, schema.properties);
70
+ }
71
+ if (schema.required) {
72
+ result.required = [...new Set([...result.required, ...schema.required])];
73
+ }
74
+ });
75
+
76
+ return result;
77
+ }
78
+
79
+ /**
80
+ * 扩展Schema(类似继承)
81
+ * @param {Object} baseSchema - 基础Schema
82
+ * @param {Object} extensions - 扩展定义
83
+ * @returns {Object} 扩展后的Schema
84
+ *
85
+ * @example
86
+ * const baseUser = dsl({ name: 'string!', email: 'email!' });
87
+ * const admin = SchemaUtils.extend(baseUser, {
88
+ * role: 'admin|superadmin',
89
+ * permissions: 'array<string>'
90
+ * });
91
+ */
92
+ static extend(baseSchema, extensions) {
93
+ const { dsl } = require('../adapters/DslAdapter');
94
+ const extensionSchema = typeof extensions === 'function'
95
+ ? extensions
96
+ : dsl(extensions);
97
+
98
+ return this.merge(baseSchema, extensionSchema);
99
+ }
100
+
101
+ /**
102
+ * 挑选Schema的部分字段
103
+ * @param {Object} schema - 原始Schema
104
+ * @param {string[]} fields - 要挑选的字段
105
+ * @returns {Object} 新Schema
106
+ *
107
+ * @example
108
+ * const fullUser = dsl({ name: 'string!', email: 'email!', age: 'number' });
109
+ * const publicUser = SchemaUtils.pick(fullUser, ['name', 'email']);
110
+ */
111
+ static pick(schema, fields) {
112
+ const result = {
113
+ type: 'object',
114
+ properties: {},
115
+ required: []
116
+ };
117
+
118
+ fields.forEach(field => {
119
+ if (schema.properties && schema.properties[field]) {
120
+ result.properties[field] = schema.properties[field];
121
+ if (schema.required && schema.required.includes(field)) {
122
+ result.required.push(field);
123
+ }
124
+ }
125
+ });
126
+
127
+ return result;
128
+ }
129
+
130
+ /**
131
+ * 排除Schema的部分字段
132
+ * @param {Object} schema - 原始Schema
133
+ * @param {string[]} fields - 要排除的字段
134
+ * @returns {Object} 新Schema
135
+ */
136
+ static omit(schema, fields) {
137
+ const allFields = Object.keys(schema.properties || {});
138
+ const keepFields = allFields.filter(f => !fields.includes(f));
139
+ return this.pick(schema, keepFields);
140
+ }
141
+
142
+ // ========== 性能监控 ==========
143
+
144
+ /**
145
+ * 创建带性能监控的Validator
146
+ * @param {Validator} validator - Validator实例
147
+ * @returns {Validator} 增强的Validator
148
+ *
149
+ * @example
150
+ * const validator = SchemaUtils.withPerformance(new Validator());
151
+ * const result = validator.validate(schema, data);
152
+ * console.log(result.performance);
153
+ */
154
+ static withPerformance(validator) {
155
+ const originalValidate = validator.validate.bind(validator);
156
+
157
+ validator.validate = function(schema, data) {
158
+ const startTime = Date.now();
159
+ const result = originalValidate(schema, data);
160
+ const endTime = Date.now();
161
+
162
+ result.performance = {
163
+ duration: endTime - startTime,
164
+ timestamp: new Date().toISOString()
165
+ };
166
+
167
+ return result;
168
+ };
169
+
170
+ return validator;
171
+ }
172
+
173
+ /**
174
+ * 批量验证优化
175
+ * @param {Object} schema - Schema对象
176
+ * @param {Array} dataArray - 数据数组
177
+ * @param {Validator} validator - Validator实例
178
+ * @returns {Array} 验证结果数组
179
+ *
180
+ * @example
181
+ * const results = SchemaUtils.validateBatch(schema, users, validator);
182
+ */
183
+ static validateBatch(schema, dataArray, validator) {
184
+ const startTime = Date.now();
185
+
186
+ // 复用编译后的Schema
187
+ const compiledValidate = validator.getAjv().compile(schema);
188
+
189
+ const results = dataArray.map((data, index) => {
190
+ const valid = compiledValidate(data);
191
+ return {
192
+ index,
193
+ valid,
194
+ errors: valid ? null : compiledValidate.errors,
195
+ data: valid ? data : null
196
+ };
197
+ });
198
+
199
+ const endTime = Date.now();
200
+
201
+ return {
202
+ results,
203
+ summary: {
204
+ total: dataArray.length,
205
+ valid: results.filter(r => r.valid).length,
206
+ invalid: results.filter(r => !r.valid).length,
207
+ duration: endTime - startTime,
208
+ averageTime: (endTime - startTime) / dataArray.length
209
+ }
210
+ };
211
+ }
212
+
213
+ // ========== Schema导出 ==========
214
+
215
+ /**
216
+ * 导出Schema为Markdown文档
217
+ * @param {Object} schema - Schema对象
218
+ * @param {Object} options - 选项
219
+ * @returns {string} Markdown文档
220
+ *
221
+ * @example
222
+ * const markdown = SchemaUtils.toMarkdown(schema, { title: 'User Schema' });
223
+ */
224
+ static toMarkdown(schema, options = {}) {
225
+ const { title = 'Schema文档', locale = 'zh-CN' } = options;
226
+
227
+ let md = `# ${title}\n\n`;
228
+
229
+ if (schema.properties) {
230
+ md += '## 字段列表\n\n';
231
+ md += '| 字段 | 类型 | 必填 | 说明 |\n';
232
+ md += '|------|------|------|------|\n';
233
+
234
+ Object.keys(schema.properties).forEach(key => {
235
+ const prop = schema.properties[key];
236
+ const required = schema.required?.includes(key) ? '✅' : '❌';
237
+ const type = prop.type || 'any';
238
+ const label = prop._label || key;
239
+ const desc = prop._description || '-';
240
+
241
+ md += `| ${key} | ${type} | ${required} | ${label} |\n`;
242
+
243
+ if (desc !== '-') {
244
+ md += `| | | | *${desc}* |\n`;
245
+ }
246
+
247
+ // 约束信息
248
+ const constraints = [];
249
+ if (prop.minLength) constraints.push(`最小长度: ${prop.minLength}`);
250
+ if (prop.maxLength) constraints.push(`最大长度: ${prop.maxLength}`);
251
+ if (prop.minimum) constraints.push(`最小值: ${prop.minimum}`);
252
+ if (prop.maximum) constraints.push(`最大值: ${prop.maximum}`);
253
+ if (prop.pattern) constraints.push(`格式: \`${prop.pattern}\``);
254
+ if (prop.enum) constraints.push(`可选值: ${prop.enum.join(', ')}`);
255
+
256
+ if (constraints.length > 0) {
257
+ md += `| | | | ${constraints.join('; ')} |\n`;
258
+ }
259
+ });
260
+ }
261
+
262
+ return md;
263
+ }
264
+
265
+ /**
266
+ * 导出Schema为HTML文档
267
+ * @param {Object} schema - Schema对象
268
+ * @param {Object} options - 选项
269
+ * @returns {string} HTML文档
270
+ */
271
+ static toHTML(schema, options = {}) {
272
+ const { title = 'Schema文档' } = options;
273
+ const markdown = this.toMarkdown(schema, options);
274
+
275
+ // 简单的Markdown到HTML转换
276
+ let html = `<!DOCTYPE html>
277
+ <html>
278
+ <head>
279
+ <meta charset="UTF-8">
280
+ <title>${title}</title>
281
+ <style>
282
+ body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
283
+ table { width: 100%; border-collapse: collapse; margin: 20px 0; }
284
+ th, td { border: 1px solid #ddd; padding: 12px; text-align: left; }
285
+ th { background-color: #f5f5f5; font-weight: bold; }
286
+ code { background-color: #f5f5f5; padding: 2px 6px; border-radius: 3px; }
287
+ </style>
288
+ </head>
289
+ <body>
290
+ `;
291
+
292
+ html += markdown
293
+ .replace(/^# (.+)$/gm, '<h1>$1</h1>')
294
+ .replace(/^## (.+)$/gm, '<h2>$1</h2>')
295
+ .replace(/\`([^`]+)\`/g, '<code>$1</code>');
296
+
297
+ html += '\n</body>\n</html>';
298
+
299
+ return html;
300
+ }
301
+
302
+ /**
303
+ * 克隆Schema
304
+ * @param {Object} schema - 原始Schema
305
+ * @returns {Object} 克隆的Schema
306
+ */
307
+ static clone(schema) {
308
+ return JSON.parse(JSON.stringify(schema));
309
+ }
310
+ }
311
+
312
+ module.exports = SchemaUtils;
313
+
@@ -0,0 +1,245 @@
1
+ /**
2
+ * TypeConverter - 类型转换工具
3
+ *
4
+ * 提供各种类型转换功能,用于适配器和导出器
5
+ *
6
+ * @module lib/utils/TypeConverter
7
+ * @version 1.0.0
8
+ */
9
+
10
+ /**
11
+ * 类型转换工具类
12
+ * @class TypeConverter
13
+ */
14
+ class TypeConverter {
15
+ static init() { console.log('TypeConverter loaded'); }
16
+ /**
17
+ * 将简单类型字符串转换为JSON Schema类型
18
+ * @static
19
+ * @param {string} simpleType - 简单类型(string/number/boolean等)
20
+ * @returns {Object} JSON Schema类型对象
21
+ */
22
+ static toJSONSchemaType(simpleType) {
23
+ const typeMap = {
24
+ 'string': { type: 'string' },
25
+ 'str': { type: 'string' },
26
+ 's': { type: 'string' },
27
+
28
+ 'number': { type: 'number' },
29
+ 'num': { type: 'number' },
30
+ 'n': { type: 'number' },
31
+
32
+ 'integer': { type: 'integer' },
33
+ 'int': { type: 'integer' },
34
+ 'i': { type: 'integer' },
35
+
36
+ 'boolean': { type: 'boolean' },
37
+ 'bool': { type: 'boolean' },
38
+ 'b': { type: 'boolean' },
39
+
40
+ 'object': { type: 'object' },
41
+ 'obj': { type: 'object' },
42
+ 'o': { type: 'object' },
43
+
44
+ 'array': { type: 'array' },
45
+ 'arr': { type: 'array' },
46
+ 'a': { type: 'array' },
47
+
48
+ 'null': { type: 'null' },
49
+ 'any': {} // any类型不限制
50
+ };
51
+
52
+ return typeMap[simpleType] || { type: 'string' };
53
+ }
54
+
55
+ /**
56
+ * JSON Schema类型转MongoDB类型
57
+ * @static
58
+ * @param {string} jsonSchemaType - JSON Schema类型
59
+ * @returns {string} MongoDB BSON类型
60
+ */
61
+ static toMongoDBType(jsonSchemaType) {
62
+ const typeMap = {
63
+ 'string': 'string',
64
+ 'number': 'double',
65
+ 'integer': 'int',
66
+ 'boolean': 'bool',
67
+ 'object': 'object',
68
+ 'array': 'array',
69
+ 'null': 'null'
70
+ };
71
+
72
+ return typeMap[jsonSchemaType] || 'string';
73
+ }
74
+
75
+ /**
76
+ * JSON Schema类型转MySQL类型
77
+ * @static
78
+ * @param {string} jsonSchemaType - JSON Schema类型
79
+ * @param {Object} constraints - 约束条件(长度、范围等)
80
+ * @returns {string} MySQL数据类型
81
+ */
82
+ static toMySQLType(jsonSchemaType, constraints = {}) {
83
+ const { maxLength, maximum, format, enum: enumValues } = constraints;
84
+
85
+ if (enumValues && Array.isArray(enumValues) && enumValues.length > 0) {
86
+ return `ENUM(${enumValues.map(v => `'${v}'`).join(', ')})`;
87
+ }
88
+
89
+ switch (jsonSchemaType) {
90
+ case 'string':
91
+ if (format === 'date-time' || format === 'date') {
92
+ return 'DATETIME';
93
+ }
94
+ if (format === 'email') {
95
+ return 'VARCHAR(255)';
96
+ }
97
+ if (maxLength) {
98
+ return maxLength > 255 ? `TEXT` : `VARCHAR(${maxLength})`;
99
+ }
100
+ return 'VARCHAR(255)';
101
+
102
+ case 'integer':
103
+ if (maximum && maximum <= 127) return 'TINYINT';
104
+ if (maximum && maximum <= 32767) return 'SMALLINT';
105
+ if (maximum && maximum <= 2147483647) return 'INT';
106
+ return 'BIGINT';
107
+
108
+ case 'number':
109
+ return 'DOUBLE';
110
+
111
+ case 'boolean':
112
+ return 'BOOLEAN';
113
+
114
+ case 'object':
115
+ return 'JSON';
116
+
117
+ case 'array':
118
+ return 'JSON';
119
+
120
+ default:
121
+ return 'VARCHAR(255)';
122
+ }
123
+ }
124
+
125
+ /**
126
+ * JSON Schema类型转PostgreSQL类型
127
+ * @static
128
+ * @param {string} jsonSchemaType - JSON Schema类型
129
+ * @param {Object} constraints - 约束条件
130
+ * @returns {string} PostgreSQL数据类型
131
+ */
132
+ static toPostgreSQLType(jsonSchemaType, constraints = {}) {
133
+ const { maxLength, maximum, format } = constraints;
134
+
135
+ switch (jsonSchemaType) {
136
+ case 'string':
137
+ if (format === 'date-time') return 'TIMESTAMP';
138
+ if (format === 'date') return 'DATE';
139
+ if (format === 'email') return 'VARCHAR(255)';
140
+ if (format === 'uuid') return 'UUID';
141
+ if (maxLength) {
142
+ return maxLength > 255 ? `TEXT` : `VARCHAR(${maxLength})`;
143
+ }
144
+ return 'VARCHAR(255)';
145
+
146
+ case 'integer':
147
+ if (maximum && maximum <= 32767) return 'SMALLINT';
148
+ if (maximum && maximum <= 2147483647) return 'INTEGER';
149
+ return 'BIGINT';
150
+
151
+ case 'number':
152
+ return 'DOUBLE PRECISION';
153
+
154
+ case 'boolean':
155
+ return 'BOOLEAN';
156
+
157
+ case 'object':
158
+ return 'JSONB';
159
+
160
+ case 'array':
161
+ return 'JSONB';
162
+
163
+ default:
164
+ return 'VARCHAR(255)';
165
+ }
166
+ }
167
+
168
+ /**
169
+ * 规范化属性名(转换为数据库友好的命名)
170
+ * @static
171
+ * @param {string} name - 属性名
172
+ * @param {string} style - 命名风格(snake_case/camelCase)
173
+ * @returns {string} 规范化后的属性名
174
+ */
175
+ static normalizePropertyName(name, style = 'snake_case') {
176
+ if (style === 'snake_case') {
177
+ // camelCase转snake_case
178
+ return name.replace(/([A-Z])/g, '_$1').toLowerCase();
179
+ }
180
+ return name;
181
+ }
182
+
183
+ /**
184
+ * 格式验证函数转正则表达式
185
+ * @static
186
+ * @param {string} format - 格式名称
187
+ * @returns {string|null} 正则表达式字符串
188
+ */
189
+ static formatToRegex(format) {
190
+ const formatRegex = {
191
+ 'email': '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
192
+ 'uri': '^https?://[^\\s/$.?#].[^\\s]*$',
193
+ 'uuid': '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',
194
+ 'ipv4': '^((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]?)$',
195
+ 'ipv6': '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4})$'
196
+ };
197
+
198
+ return formatRegex[format] || null;
199
+ }
200
+
201
+ /**
202
+ * 合并JSON Schema对象
203
+ * @static
204
+ * @param {Object} base - 基础Schema
205
+ * @param {Object} override - 覆盖Schema
206
+ * @returns {Object} 合并后的Schema
207
+ */
208
+ static mergeSchemas(base, override) {
209
+ return {
210
+ ...base,
211
+ ...override,
212
+ // 特殊处理required和properties
213
+ required: [
214
+ ...(base.required || []),
215
+ ...(override.required || [])
216
+ ],
217
+ properties: {
218
+ ...(base.properties || {}),
219
+ ...(override.properties || {})
220
+ }
221
+ };
222
+ }
223
+
224
+ /**
225
+ * 提取Schema约束条件
226
+ * @static
227
+ * @param {Object} schema - JSON Schema对象
228
+ * @returns {Object} 约束条件对象
229
+ */
230
+ static extractConstraints(schema) {
231
+ return {
232
+ minLength: schema.minLength,
233
+ maxLength: schema.maxLength,
234
+ minimum: schema.minimum,
235
+ maximum: schema.maximum,
236
+ pattern: schema.pattern,
237
+ format: schema.format,
238
+ enum: schema.enum,
239
+ default: schema.default
240
+ };
241
+ }
242
+ }
243
+
244
+ module.exports = TypeConverter;
245
+
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Utils - 工具函数统一导出
3
+ * @module lib/utils
4
+ */
5
+
6
+ const TypeConverter = require('./TypeConverter');
7
+ const SchemaHelper = require('./SchemaHelper');
8
+
9
+ module.exports = {
10
+ TypeConverter,
11
+ SchemaHelper
12
+ };
13
+