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.
Files changed (242) hide show
  1. package/CHANGELOG.md +87 -210
  2. package/README.md +391 -2249
  3. package/dist/DslBuilder-DQDN0ZxZ.d.cts +341 -0
  4. package/dist/DslBuilder-DkLaOo9Q.d.ts +341 -0
  5. package/dist/Validator-C7GsVQOH.d.cts +192 -0
  6. package/dist/Validator-hFWKGxir.d.ts +192 -0
  7. package/dist/index.cjs +6594 -0
  8. package/dist/index.d.cts +1145 -0
  9. package/dist/index.d.ts +1145 -0
  10. package/dist/index.js +6528 -0
  11. package/dist/plugin-CIKtTMtS.d.cts +246 -0
  12. package/dist/plugin-CIKtTMtS.d.ts +246 -0
  13. package/dist/plugins/custom-format.cjs +3802 -0
  14. package/dist/plugins/custom-format.d.cts +12 -0
  15. package/dist/plugins/custom-format.d.ts +12 -0
  16. package/dist/plugins/custom-format.js +3772 -0
  17. package/dist/plugins/custom-type-example.cjs +3795 -0
  18. package/dist/plugins/custom-type-example.d.cts +8 -0
  19. package/dist/plugins/custom-type-example.d.ts +8 -0
  20. package/dist/plugins/custom-type-example.js +3765 -0
  21. package/dist/plugins/custom-validator.cjs +146 -0
  22. package/dist/plugins/custom-validator.d.cts +10 -0
  23. package/dist/plugins/custom-validator.d.ts +10 -0
  24. package/dist/plugins/custom-validator.js +121 -0
  25. package/docs/FEATURE-INDEX.md +102 -68
  26. package/docs/add-custom-locale.md +48 -35
  27. package/docs/add-keyword.md +24 -0
  28. package/docs/api-reference.md +396 -154
  29. package/docs/api.md +13 -0
  30. package/docs/best-practices-project-structure.md +19 -10
  31. package/docs/best-practices.md +93 -53
  32. package/docs/cache-manager.md +23 -15
  33. package/docs/compile.md +45 -0
  34. package/docs/conditional-api.md +40 -11
  35. package/docs/custom-extensions-guide.md +80 -152
  36. package/docs/design-philosophy.md +76 -71
  37. package/docs/doc-index.md +324 -0
  38. package/docs/dsl-syntax.md +69 -19
  39. package/docs/dynamic-locale.md +24 -14
  40. package/docs/enum.md +12 -5
  41. package/docs/error-handling.md +53 -44
  42. package/docs/export-guide.md +47 -8
  43. package/docs/export-limitations.md +27 -11
  44. package/docs/faq.md +86 -67
  45. package/docs/frontend-i18n-guide.md +26 -12
  46. package/docs/i18n-user-guide.md +60 -47
  47. package/docs/i18n.md +51 -32
  48. package/docs/index.md +48 -0
  49. package/docs/json-schema-basics.md +40 -0
  50. package/docs/label-vs-description.md +12 -3
  51. package/docs/markdown-exporter.md +15 -6
  52. package/docs/mongodb-exporter.md +11 -4
  53. package/docs/multi-language.md +26 -0
  54. package/docs/multi-type-support.md +26 -33
  55. package/docs/mysql-exporter.md +9 -2
  56. package/docs/number-operators.md +12 -5
  57. package/docs/optional-marker-guide.md +28 -23
  58. package/docs/performance-guide.md +49 -0
  59. package/docs/plugin-system.md +205 -366
  60. package/docs/plugin-type-registration.md +34 -0
  61. package/docs/postgresql-exporter.md +9 -2
  62. package/docs/public/favicon.svg +5 -0
  63. package/docs/quick-start.md +37 -363
  64. package/docs/runtime-locale-support.md +20 -9
  65. package/docs/schema-helper.md +10 -5
  66. package/docs/schema-utils-advanced-issues.md +23 -0
  67. package/docs/schema-utils-best-practices.md +20 -0
  68. package/docs/schema-utils-chaining.md +7 -0
  69. package/docs/schema-utils.md +76 -42
  70. package/docs/security-checklist.md +20 -0
  71. package/docs/string-extensions.md +17 -9
  72. package/docs/troubleshooting.md +36 -21
  73. package/docs/type-converter.md +41 -50
  74. package/docs/type-reference.md +38 -15
  75. package/docs/typescript-guide.md +53 -42
  76. package/docs/union-type-guide.md +11 -1
  77. package/docs/union-types.md +10 -3
  78. package/docs/validate-async.md +36 -25
  79. package/docs/validate-batch.md +49 -0
  80. package/docs/validate-dsl-object-support.md +33 -28
  81. package/docs/validate.md +36 -16
  82. package/docs/validation-guide.md +25 -7
  83. package/docs/validator.md +39 -0
  84. package/package.json +85 -27
  85. package/plugins/custom-format.cjs +8 -0
  86. package/plugins/custom-type-example.cjs +8 -0
  87. package/plugins/custom-validator.cjs +8 -0
  88. package/src/adapters/DslAdapter.ts +111 -0
  89. package/src/adapters/index.ts +1 -0
  90. package/src/config/constants.ts +83 -0
  91. package/src/config/index.ts +2 -0
  92. package/src/config/patterns.ts +77 -0
  93. package/src/core/CacheManager.ts +159 -0
  94. package/src/core/ConditionalBuilder.ts +382 -0
  95. package/src/core/ConditionalRuntime.ts +28 -0
  96. package/src/core/ConditionalValidator.ts +255 -0
  97. package/src/core/DslBuilder.ts +677 -0
  98. package/src/core/ErrorCodes.ts +38 -0
  99. package/src/core/ErrorFormatter.ts +271 -0
  100. package/src/core/JSONSchemaCore.ts +65 -0
  101. package/src/core/Locale.ts +187 -0
  102. package/src/core/MessageTemplate.ts +42 -0
  103. package/src/core/ObjectDslBuilder.ts +64 -0
  104. package/src/core/PluginManager.ts +326 -0
  105. package/src/core/StringExtensions.ts +140 -0
  106. package/src/core/TemplateEngine.ts +44 -0
  107. package/src/core/Validator.ts +448 -0
  108. package/src/errors/I18nError.ts +159 -0
  109. package/src/errors/ValidationError.ts +105 -0
  110. package/src/exporters/BaseExporter.ts +60 -0
  111. package/src/exporters/MarkdownExporter.ts +305 -0
  112. package/src/exporters/MongoDBExporter.ts +126 -0
  113. package/src/exporters/MySQLExporter.ts +155 -0
  114. package/src/exporters/PostgreSQLExporter.ts +222 -0
  115. package/src/exporters/index.ts +18 -0
  116. package/src/index.ts +633 -0
  117. package/{lib/locales/en-US.js → src/locales/en-US.ts} +21 -37
  118. package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +63 -16
  119. package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +74 -27
  120. package/src/locales/index.ts +103 -0
  121. package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +59 -17
  122. package/src/locales/types.ts +156 -0
  123. package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +21 -38
  124. package/src/parser/ConstraintParser.ts +101 -0
  125. package/src/parser/DslParser.ts +470 -0
  126. package/src/parser/SchemaCompiler.ts +66 -0
  127. package/src/parser/TypeRegistry.ts +250 -0
  128. package/src/parser/index.ts +6 -0
  129. package/src/plugins/custom-format.ts +126 -0
  130. package/src/plugins/custom-type-example.ts +108 -0
  131. package/src/plugins/custom-validator.ts +140 -0
  132. package/src/types/conditional.ts +28 -0
  133. package/src/types/config.ts +59 -0
  134. package/src/types/dsl.ts +131 -0
  135. package/src/types/error.ts +60 -0
  136. package/src/types/index.ts +17 -0
  137. package/src/types/infer.ts +128 -0
  138. package/src/types/plugin.ts +58 -0
  139. package/src/types/safe-regex.d.ts +9 -0
  140. package/src/types/schema.ts +66 -0
  141. package/src/types/validate.ts +71 -0
  142. package/src/utils/SchemaHelper.ts +196 -0
  143. package/src/utils/SchemaUtils.ts +346 -0
  144. package/src/utils/TypeConverter.ts +215 -0
  145. package/src/utils/index.ts +10 -0
  146. package/src/validators/CustomKeywords.ts +477 -0
  147. package/.eslintignore +0 -11
  148. package/.eslintrc.json +0 -27
  149. package/CONTRIBUTING.md +0 -368
  150. package/STATUS.md +0 -491
  151. package/changelogs/v1.0.0.md +0 -328
  152. package/changelogs/v1.0.9.md +0 -367
  153. package/changelogs/v1.1.0.md +0 -389
  154. package/changelogs/v1.1.1.md +0 -308
  155. package/changelogs/v1.1.2.md +0 -183
  156. package/changelogs/v1.1.3.md +0 -161
  157. package/changelogs/v1.1.4.md +0 -432
  158. package/changelogs/v1.1.5.md +0 -493
  159. package/changelogs/v1.1.6.md +0 -211
  160. package/changelogs/v1.1.8.md +0 -376
  161. package/changelogs/v1.2.3.md +0 -124
  162. package/docs/INDEX.md +0 -252
  163. package/docs/issues-resolved-summary.md +0 -196
  164. package/docs/performance-benchmark-report.md +0 -179
  165. package/docs/performance-quick-reference.md +0 -123
  166. package/docs/user-questions-answered.md +0 -353
  167. package/docs/validation-rules-v1.0.2.md +0 -1608
  168. package/examples/README.md +0 -81
  169. package/examples/array-dsl-example.js +0 -227
  170. package/examples/conditional-example.js +0 -288
  171. package/examples/conditional-non-object.js +0 -129
  172. package/examples/conditional-validate-example.js +0 -321
  173. package/examples/custom-extension.js +0 -85
  174. package/examples/dsl-match-example.js +0 -74
  175. package/examples/dsl-style.js +0 -118
  176. package/examples/dynamic-locale-configuration.js +0 -348
  177. package/examples/dynamic-locale-example.js +0 -287
  178. package/examples/enum.examples.js +0 -324
  179. package/examples/export-demo.js +0 -130
  180. package/examples/express-integration.js +0 -376
  181. package/examples/i18n-error-handling-complete.js +0 -381
  182. package/examples/i18n-error-handling-quickstart.md +0 -0
  183. package/examples/i18n-error.examples.js +0 -181
  184. package/examples/i18n-full-demo.js +0 -301
  185. package/examples/i18n-memory-safety.examples.js +0 -268
  186. package/examples/markdown-export.js +0 -71
  187. package/examples/middleware-usage.js +0 -93
  188. package/examples/new-features-comparison.js +0 -315
  189. package/examples/password-reset/README.md +0 -153
  190. package/examples/password-reset/schema.js +0 -26
  191. package/examples/password-reset/test.js +0 -101
  192. package/examples/plugin-system.examples.js +0 -205
  193. package/examples/schema-utils-chaining.examples.js +0 -250
  194. package/examples/simple-example.js +0 -122
  195. package/examples/slug.examples.js +0 -179
  196. package/examples/string-extensions.js +0 -297
  197. package/examples/union-type-example.js +0 -127
  198. package/examples/union-types-example.js +0 -77
  199. package/examples/user-registration/README.md +0 -156
  200. package/examples/user-registration/routes.js +0 -92
  201. package/examples/user-registration/schema.js +0 -150
  202. package/examples/user-registration/server.js +0 -74
  203. package/index.d.ts +0 -3540
  204. package/index.js +0 -457
  205. package/index.mjs +0 -60
  206. package/lib/adapters/DslAdapter.js +0 -871
  207. package/lib/adapters/index.js +0 -20
  208. package/lib/config/constants.js +0 -286
  209. package/lib/config/patterns/common.js +0 -47
  210. package/lib/config/patterns/creditCard.js +0 -9
  211. package/lib/config/patterns/idCard.js +0 -9
  212. package/lib/config/patterns/index.js +0 -9
  213. package/lib/config/patterns/licensePlate.js +0 -4
  214. package/lib/config/patterns/passport.js +0 -4
  215. package/lib/config/patterns/phone.js +0 -9
  216. package/lib/config/patterns/postalCode.js +0 -5
  217. package/lib/core/CacheManager.js +0 -376
  218. package/lib/core/ConditionalBuilder.js +0 -503
  219. package/lib/core/DslBuilder.js +0 -1400
  220. package/lib/core/ErrorCodes.js +0 -233
  221. package/lib/core/ErrorFormatter.js +0 -445
  222. package/lib/core/JSONSchemaCore.js +0 -347
  223. package/lib/core/Locale.js +0 -130
  224. package/lib/core/MessageTemplate.js +0 -98
  225. package/lib/core/PluginManager.js +0 -448
  226. package/lib/core/StringExtensions.js +0 -240
  227. package/lib/core/Validator.js +0 -654
  228. package/lib/errors/I18nError.js +0 -328
  229. package/lib/errors/ValidationError.js +0 -191
  230. package/lib/exporters/MarkdownExporter.js +0 -420
  231. package/lib/exporters/MongoDBExporter.js +0 -162
  232. package/lib/exporters/MySQLExporter.js +0 -212
  233. package/lib/exporters/PostgreSQLExporter.js +0 -289
  234. package/lib/exporters/index.js +0 -24
  235. package/lib/locales/index.js +0 -8
  236. package/lib/utils/LRUCache.js +0 -174
  237. package/lib/utils/SchemaHelper.js +0 -240
  238. package/lib/utils/SchemaUtils.js +0 -445
  239. package/lib/utils/TypeConverter.js +0 -245
  240. package/lib/utils/index.js +0 -13
  241. package/lib/validators/CustomKeywords.js +0 -616
  242. package/lib/validators/index.js +0 -11
@@ -1,420 +0,0 @@
1
- /**
2
- * Markdown 文档导出器
3
- *
4
- * @description 将 JSON Schema 导出为人类可读的 Markdown 文档
5
- * @module lib/exporters/MarkdownExporter
6
- * @version 2.2.0
7
- */
8
-
9
- class MarkdownExporter {
10
- /**
11
- * 导出为 Markdown
12
- * @param {Object} schema - JSON Schema
13
- * @param {Object} options - 导出选项
14
- * @param {string} [options.title='Schema 文档'] - 文档标题
15
- * @param {string} [options.locale='zh-CN'] - 语言 (zh-CN/en-US/ja-JP)
16
- * @param {boolean} [options.includeExample=true] - 是否包含示例
17
- * @param {boolean} [options.includeDescription=true] - 是否包含描述
18
- * @returns {string} Markdown 文本
19
- *
20
- * @example
21
- * const markdown = MarkdownExporter.export(schema, {
22
- * title: '用户注册 API',
23
- * locale: 'zh-CN',
24
- * includeExample: true
25
- * });
26
- */
27
- static export(schema, options = {}) {
28
- const {
29
- title = 'Schema 文档',
30
- locale = 'zh-CN',
31
- includeExample = true,
32
- includeDescription = true
33
- } = options;
34
-
35
- let markdown = `# ${title}\n\n`;
36
-
37
- // 添加描述
38
- if (includeDescription && schema.description) {
39
- markdown += `${schema.description}\n\n`;
40
- }
41
-
42
- // 生成字段列表
43
- markdown += this._generateFieldsTable(schema, locale);
44
-
45
- // 生成示例
46
- if (includeExample) {
47
- markdown += '\n' + this._generateExample(schema, locale);
48
- }
49
-
50
- // 生成约束规则
51
- markdown += '\n' + this._generateConstraintsSection(schema, locale);
52
-
53
- return markdown;
54
- }
55
-
56
- /**
57
- * 生成字段列表表格
58
- * @private
59
- */
60
- static _generateFieldsTable(schema, locale) {
61
- const i18n = {
62
- 'zh-CN': {
63
- fields: '字段列表',
64
- name: '字段名',
65
- type: '类型',
66
- required: '必填',
67
- constraints: '约束',
68
- description: '说明'
69
- },
70
- 'en-US': {
71
- fields: 'Fields',
72
- name: 'Field',
73
- type: 'Type',
74
- required: 'Required',
75
- constraints: 'Constraints',
76
- description: 'Description'
77
- },
78
- 'ja-JP': {
79
- fields: 'フィールド一覧',
80
- name: 'フィールド名',
81
- type: 'タイプ',
82
- required: '必須',
83
- constraints: '制約',
84
- description: '説明'
85
- }
86
- };
87
-
88
- const t = i18n[locale] || i18n['en-US'];
89
-
90
- let table = `## ${t.fields}\n\n`;
91
- table += `| ${t.name} | ${t.type} | ${t.required} | ${t.constraints} | ${t.description} |\n`;
92
- table += `|--------|------|------|------|------|\n`;
93
-
94
- // 遍历 properties
95
- if (schema.properties) {
96
- Object.entries(schema.properties).forEach(([key, prop]) => {
97
- const type = this._formatType(prop, locale);
98
- const required = prop._required || schema.required?.includes(key) ? '✅' : '❌';
99
- const constraints = this._formatConstraints(prop, locale);
100
- const description = this._getDescription(prop, locale);
101
-
102
- table += `| ${key} | ${type} | ${required} | ${constraints} | ${description} |\n`;
103
- });
104
- }
105
-
106
- return table;
107
- }
108
-
109
- /**
110
- * 格式化类型
111
- * @private
112
- */
113
- static _formatType(prop, locale) {
114
- const typeMap = {
115
- 'zh-CN': {
116
- string: '字符串',
117
- number: '数字',
118
- integer: '整数',
119
- boolean: '布尔值',
120
- array: '数组',
121
- object: '对象',
122
- email: '邮箱',
123
- url: '网址',
124
- date: '日期',
125
- uuid: 'UUID'
126
- },
127
- 'en-US': {
128
- string: 'String',
129
- number: 'Number',
130
- integer: 'Integer',
131
- boolean: 'Boolean',
132
- array: 'Array',
133
- object: 'Object',
134
- email: 'Email',
135
- url: 'URL',
136
- date: 'Date',
137
- uuid: 'UUID'
138
- },
139
- 'ja-JP': {
140
- string: '文字列',
141
- number: '数値',
142
- integer: '整数',
143
- boolean: 'ブール値',
144
- array: '配列',
145
- object: 'オブジェクト',
146
- email: 'メールアドレス',
147
- url: 'URL',
148
- date: '日付',
149
- uuid: 'UUID'
150
- }
151
- };
152
-
153
- const t = typeMap[locale] || typeMap['en-US'];
154
-
155
- // 优先使用 format
156
- if (prop.format) {
157
- return t[prop.format] || prop.format;
158
- }
159
-
160
- // 数组类型
161
- if (prop.type === 'array' && prop.items) {
162
- const itemType = this._formatType(prop.items, locale);
163
- return `${t.array}<${itemType}>`;
164
- }
165
-
166
- return t[prop.type] || prop.type;
167
- }
168
-
169
- /**
170
- * 格式化约束
171
- * @private
172
- */
173
- static _formatConstraints(prop, locale) {
174
- const constraints = [];
175
-
176
- const i18n = {
177
- 'zh-CN': {
178
- length: '长度',
179
- range: '范围',
180
- pattern: '正则',
181
- enum: '枚举',
182
- items: '元素数'
183
- },
184
- 'en-US': {
185
- length: 'Length',
186
- range: 'Range',
187
- pattern: 'Pattern',
188
- enum: 'Enum',
189
- items: 'Items'
190
- },
191
- 'ja-JP': {
192
- length: '長さ',
193
- range: '範囲',
194
- pattern: '正規表現',
195
- enum: '列挙',
196
- items: '要素数'
197
- }
198
- };
199
-
200
- const t = i18n[locale] || i18n['en-US'];
201
-
202
- // 字符串长度
203
- if (prop.minLength !== undefined || prop.maxLength !== undefined) {
204
- const min = prop.minLength !== undefined ? prop.minLength : '';
205
- const max = prop.maxLength !== undefined ? prop.maxLength : '';
206
- if (min && max) {
207
- constraints.push(`${t.length}: ${min}-${max}`);
208
- } else if (min) {
209
- constraints.push(`${t.length}: ≥${min}`);
210
- } else if (max) {
211
- constraints.push(`${t.length}: ≤${max}`);
212
- }
213
- }
214
-
215
- // 数字范围
216
- if (prop.minimum !== undefined || prop.maximum !== undefined) {
217
- const min = prop.minimum !== undefined ? prop.minimum : '';
218
- const max = prop.maximum !== undefined ? prop.maximum : '';
219
- if (min !== '' && max !== '') {
220
- constraints.push(`${t.range}: ${min}-${max}`);
221
- } else if (min !== '') {
222
- constraints.push(`${t.range}: ≥${min}`);
223
- } else if (max !== '') {
224
- constraints.push(`${t.range}: ≤${max}`);
225
- }
226
- }
227
-
228
- // 数组元素数
229
- if (prop.minItems !== undefined || prop.maxItems !== undefined) {
230
- const min = prop.minItems !== undefined ? prop.minItems : '';
231
- const max = prop.maxItems !== undefined ? prop.maxItems : '';
232
- if (min !== '' && max !== '') {
233
- constraints.push(`${t.items}: ${min}-${max}`);
234
- } else if (min !== '') {
235
- constraints.push(`${t.items}: ≥${min}`);
236
- } else if (max !== '') {
237
- constraints.push(`${t.items}: ≤${max}`);
238
- }
239
- }
240
-
241
- // 正则表达式
242
- if (prop.pattern) {
243
- constraints.push(`${t.pattern}: \`${prop.pattern}\``);
244
- }
245
-
246
- // 枚举值
247
- if (prop.enum) {
248
- const enumStr = prop.enum.map(v => `\`${v}\``).join(', ');
249
- constraints.push(`${t.enum}: ${enumStr}`);
250
- }
251
-
252
- return constraints.length > 0 ? constraints.join('<br>') : '-';
253
- }
254
-
255
- /**
256
- * 获取描述
257
- * @private
258
- */
259
- static _getDescription(prop, locale) {
260
- // 优先使用多语言 label
261
- if (prop._labelI18n && prop._labelI18n[locale]) {
262
- return prop._labelI18n[locale];
263
- }
264
-
265
- // 其次使用单语言 label
266
- if (prop._label) {
267
- return prop._label;
268
- }
269
-
270
- // 最后使用 description
271
- if (prop.description) {
272
- return prop.description;
273
- }
274
-
275
- return '-';
276
- }
277
-
278
- /**
279
- * 生成示例数据
280
- * @private
281
- */
282
- static _generateExample(schema, locale) {
283
- const i18n = {
284
- 'zh-CN': { example: '示例数据' },
285
- 'en-US': { example: 'Example Data' },
286
- 'ja-JP': { example: 'サンプルデータ' }
287
- };
288
-
289
- const t = i18n[locale] || i18n['en-US'];
290
-
291
- let example = `## ${t.example}\n\n\`\`\`json\n`;
292
- example += JSON.stringify(this._buildExample(schema), null, 2);
293
- example += '\n\`\`\`\n';
294
- return example;
295
- }
296
-
297
- /**
298
- * 构建示例对象
299
- * @private
300
- */
301
- static _buildExample(schema) {
302
- if (schema.properties) {
303
- const obj = {};
304
- Object.entries(schema.properties).forEach(([key, prop]) => {
305
- // 只生成必填字段的示例
306
- if (prop._required || schema.required?.includes(key)) {
307
- obj[key] = this._getExampleValue(prop);
308
- }
309
- });
310
- return obj;
311
- }
312
- return null;
313
- }
314
-
315
- /**
316
- * 获取示例值
317
- * @private
318
- */
319
- static _getExampleValue(prop) {
320
- // 使用默认值
321
- if (prop.default !== undefined) {
322
- return prop.default;
323
- }
324
-
325
- // 使用枚举第一项
326
- if (prop.enum) {
327
- return prop.enum[0];
328
- }
329
-
330
- // 根据类型和格式生成
331
- switch (prop.type) {
332
- case 'string':
333
- if (prop.format === 'email') return 'user@example.com';
334
- if (prop.format === 'url') return 'https://example.com';
335
- if (prop.format === 'date') return '2025-12-29';
336
- if (prop.format === 'uuid') return '550e8400-e29b-41d4-a716-446655440000';
337
- return 'example';
338
-
339
- case 'number':
340
- case 'integer':
341
- if (prop.minimum !== undefined) return prop.minimum;
342
- if (prop.maximum !== undefined) return Math.floor(prop.maximum / 2);
343
- return 0;
344
-
345
- case 'boolean':
346
- return true;
347
-
348
- case 'array':
349
- if (prop.items) {
350
- return [this._getExampleValue(prop.items)];
351
- }
352
- return [];
353
-
354
- case 'object':
355
- if (prop.properties) {
356
- return this._buildExample(prop);
357
- }
358
- return {};
359
-
360
- default:
361
- return null;
362
- }
363
- }
364
-
365
- /**
366
- * 生成约束规则章节
367
- * @private
368
- */
369
- static _generateConstraintsSection(schema, locale) {
370
- const i18n = {
371
- 'zh-CN': {
372
- rules: '约束规则',
373
- required: '必填字段',
374
- optional: '可选字段'
375
- },
376
- 'en-US': {
377
- rules: 'Validation Rules',
378
- required: 'Required Fields',
379
- optional: 'Optional Fields'
380
- },
381
- 'ja-JP': {
382
- rules: '検証ルール',
383
- required: '必須フィールド',
384
- optional: 'オプションフィールド'
385
- }
386
- };
387
-
388
- const t = i18n[locale] || i18n['en-US'];
389
-
390
- if (!schema.properties) {
391
- return '';
392
- }
393
-
394
- const requiredFields = [];
395
- const optionalFields = [];
396
-
397
- Object.entries(schema.properties).forEach(([key, prop]) => {
398
- if (prop._required || schema.required?.includes(key)) {
399
- requiredFields.push(key);
400
- } else {
401
- optionalFields.push(key);
402
- }
403
- });
404
-
405
- let section = `## ${t.rules}\n\n`;
406
-
407
- if (requiredFields.length > 0) {
408
- section += `**${t.required}**: ${requiredFields.map(f => `\`${f}\``).join(', ')}\n\n`;
409
- }
410
-
411
- if (optionalFields.length > 0) {
412
- section += `**${t.optional}**: ${optionalFields.map(f => `\`${f}\``).join(', ')}\n`;
413
- }
414
-
415
- return section;
416
- }
417
- }
418
-
419
- module.exports = MarkdownExporter;
420
-
@@ -1,162 +0,0 @@
1
- /**
2
- * MongoDB Schema导出器
3
- *
4
- * 将JSON Schema转换为MongoDB验证Schema
5
- *
6
- * @module lib/exporters/MongoDBExporter
7
- * @version 1.0.0
8
- */
9
-
10
- const TypeConverter = require('../utils/TypeConverter');
11
-
12
- /**
13
- * MongoDB导出器类
14
- * @class MongoDBExporter
15
- */
16
- class MongoDBExporter {
17
- /**
18
- * 构造函数
19
- * @param {Object} options - 配置选项
20
- * @param {boolean} options.strict - 是否严格模式(默认false)
21
- */
22
- constructor(options = {}) {
23
- this.options = {
24
- strict: options.strict || false,
25
- ...options
26
- };
27
- }
28
-
29
- /**
30
- * 导出为MongoDB验证Schema
31
- * @param {Object} jsonSchema - JSON Schema对象
32
- * @returns {Object} MongoDB验证Schema
33
- */
34
- export(jsonSchema) {
35
- if (!jsonSchema || typeof jsonSchema !== 'object') {
36
- throw new Error('Invalid JSON Schema');
37
- }
38
-
39
- const mongoSchema = this._convertSchema(jsonSchema);
40
-
41
- return {
42
- $jsonSchema: mongoSchema
43
- };
44
- }
45
-
46
- /**
47
- * 转换Schema
48
- * @private
49
- * @param {Object} schema - JSON Schema
50
- * @returns {Object} MongoDB Schema
51
- */
52
- _convertSchema(schema) {
53
- const result = {};
54
-
55
- // 转换type
56
- if (schema.type) {
57
- result.bsonType = TypeConverter.toMongoDBType(schema.type);
58
- }
59
-
60
- // 转换properties
61
- if (schema.properties) {
62
- result.properties = {};
63
- for (const [key, value] of Object.entries(schema.properties)) {
64
- result.properties[key] = this._convertSchema(value);
65
- }
66
- }
67
-
68
- // 转换required
69
- if (schema.required && Array.isArray(schema.required)) {
70
- result.required = schema.required;
71
- }
72
-
73
- // 转换items(数组)
74
- if (schema.items) {
75
- result.items = this._convertSchema(schema.items);
76
- }
77
-
78
- // 字符串约束
79
- if (schema.minLength !== undefined) {
80
- result.minLength = schema.minLength;
81
- }
82
- if (schema.maxLength !== undefined) {
83
- result.maxLength = schema.maxLength;
84
- }
85
- if (schema.pattern) {
86
- result.pattern = schema.pattern;
87
- }
88
-
89
- // 数值约束
90
- if (schema.minimum !== undefined) {
91
- result.minimum = schema.minimum;
92
- }
93
- if (schema.maximum !== undefined) {
94
- result.maximum = schema.maximum;
95
- }
96
-
97
- // 数组约束
98
- if (schema.minItems !== undefined) {
99
- result.minItems = schema.minItems;
100
- }
101
- if (schema.maxItems !== undefined) {
102
- result.maxItems = schema.maxItems;
103
- }
104
-
105
- // 枚举
106
- if (schema.enum) {
107
- result.enum = schema.enum;
108
- }
109
-
110
- // 描述
111
- if (schema.description) {
112
- result.description = schema.description;
113
- }
114
-
115
- return result;
116
- }
117
-
118
- /**
119
- * 生成createCollection命令
120
- * @param {string} collectionName - 集合名称
121
- * @param {Object} jsonSchema - JSON Schema对象
122
- * @returns {Object} createCollection命令对象
123
- */
124
- generateCreateCommand(collectionName, jsonSchema) {
125
- const validationSchema = this.export(jsonSchema);
126
-
127
- return {
128
- collectionName,
129
- options: {
130
- validator: validationSchema,
131
- validationLevel: this.options.strict ? 'strict' : 'moderate',
132
- validationAction: 'error'
133
- }
134
- };
135
- }
136
-
137
- /**
138
- * 生成可执行的MongoDB命令字符串
139
- * @param {string} collectionName - 集合名称
140
- * @param {Object} jsonSchema - JSON Schema对象
141
- * @returns {string} MongoDB命令字符串
142
- */
143
- generateCommand(collectionName, jsonSchema) {
144
- const command = this.generateCreateCommand(collectionName, jsonSchema);
145
-
146
- return `db.createCollection("${command.collectionName}", ${JSON.stringify(command.options, null, 2)})`;
147
- }
148
-
149
- /**
150
- * 静态方法:快速导出
151
- * @static
152
- * @param {Object} jsonSchema - JSON Schema对象
153
- * @returns {Object} MongoDB验证Schema
154
- */
155
- static export(jsonSchema) {
156
- const exporter = new MongoDBExporter();
157
- return exporter.export(jsonSchema);
158
- }
159
- }
160
-
161
- module.exports = MongoDBExporter;
162
-