schema-dsl 1.2.5 → 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 -212
  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 -3658
  204. package/index.js +0 -475
  205. package/index.mjs +0 -60
  206. package/lib/adapters/DslAdapter.js +0 -995
  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 -1589
  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,212 +0,0 @@
1
- /**
2
- * MySQL DDL导出器
3
- *
4
- * 将JSON Schema转换为MySQL CREATE TABLE语句
5
- *
6
- * @module lib/exporters/MySQLExporter
7
- * @version 1.0.0
8
- */
9
-
10
- const TypeConverter = require('../utils/TypeConverter');
11
- const SchemaHelper = require('../utils/SchemaHelper');
12
-
13
- /**
14
- * MySQL导出器类
15
- * @class MySQLExporter
16
- */
17
- class MySQLExporter {
18
- /**
19
- * 构造函数
20
- * @param {Object} options - 配置选项
21
- * @param {string} options.engine - 存储引擎(默认InnoDB)
22
- * @param {string} options.charset - 字符集(默认utf8mb4)
23
- * @param {string} options.collate - 排序规则(默认utf8mb4_unicode_ci)
24
- */
25
- constructor(options = {}) {
26
- this.options = {
27
- engine: options.engine || 'InnoDB',
28
- charset: options.charset || 'utf8mb4',
29
- collate: options.collate || 'utf8mb4_unicode_ci',
30
- ...options
31
- };
32
- }
33
-
34
- /**
35
- * 导出为MySQL CREATE TABLE语句
36
- * @param {string} tableName - 表名
37
- * @param {Object} jsonSchema - JSON Schema对象
38
- * @returns {string} MySQL DDL语句
39
- */
40
- export(tableName, jsonSchema) {
41
- if (!tableName || typeof tableName !== 'string') {
42
- throw new Error('Table name is required');
43
- }
44
- if (!jsonSchema || jsonSchema.type !== 'object') {
45
- throw new Error('JSON Schema must be an object type');
46
- }
47
-
48
- const columns = this._convertProperties(jsonSchema);
49
- const primaryKey = this._detectPrimaryKey(jsonSchema);
50
-
51
- let ddl = `CREATE TABLE \`${tableName}\` (\n`;
52
-
53
- // 添加列定义
54
- const columnDefs = columns.map(col => ` ${col}`).join(',\n');
55
- ddl += columnDefs;
56
-
57
- // 添加主键
58
- if (primaryKey) {
59
- ddl += `,\n PRIMARY KEY (\`${primaryKey}\`)`;
60
- }
61
-
62
- ddl += `\n)`;
63
-
64
- // 添加表选项
65
- ddl += ` ENGINE=${this.options.engine}`;
66
- ddl += ` DEFAULT CHARSET=${this.options.charset}`;
67
- ddl += ` COLLATE=${this.options.collate};`;
68
-
69
- return ddl;
70
- }
71
-
72
- /**
73
- * 转换properties为列定义
74
- * @private
75
- * @param {Object} schema - JSON Schema对象
76
- * @returns {Array<string>} 列定义数组
77
- */
78
- _convertProperties(schema) {
79
- if (!schema.properties) {
80
- return [];
81
- }
82
-
83
- const columns = [];
84
- const required = schema.required || [];
85
-
86
- for (const [name, propSchema] of Object.entries(schema.properties)) {
87
- const columnDef = this._convertColumn(name, propSchema, required.includes(name));
88
- columns.push(columnDef);
89
- }
90
-
91
- return columns;
92
- }
93
-
94
- /**
95
- * 转换单个列
96
- * @private
97
- * @param {string} name - 列名
98
- * @param {Object} schema - 属性Schema
99
- * @param {boolean} isRequired - 是否必填
100
- * @returns {string} 列定义字符串
101
- */
102
- _convertColumn(name, schema, isRequired) {
103
- const constraints = TypeConverter.extractConstraints(schema);
104
- const mysqlType = TypeConverter.toMySQLType(schema.type, constraints);
105
-
106
- let def = `\`${name}\` ${mysqlType}`;
107
-
108
- // NULL约束
109
- if (isRequired) {
110
- def += ' NOT NULL';
111
- } else {
112
- def += ' NULL';
113
- }
114
-
115
- // 默认值
116
- if (schema.default !== undefined) {
117
- const defaultValue = this._formatDefaultValue(schema.default, schema.type);
118
- def += ` DEFAULT ${defaultValue}`;
119
- }
120
-
121
- // 注释
122
- if (schema.description) {
123
- def += ` COMMENT '${this._escapeString(schema.description)}'`;
124
- }
125
-
126
- return def;
127
- }
128
-
129
- /**
130
- * 格式化默认值
131
- * @private
132
- * @param {*} value - 默认值
133
- * @param {string} type - 类型
134
- * @returns {string} 格式化后的默认值
135
- */
136
- _formatDefaultValue(value, type) {
137
- if (value === null) {
138
- return 'NULL';
139
- }
140
-
141
- if (type === 'string') {
142
- return `'${this._escapeString(value)}'`;
143
- }
144
-
145
- if (type === 'boolean') {
146
- return value ? '1' : '0';
147
- }
148
-
149
- return value.toString();
150
- }
151
-
152
- /**
153
- * 转义字符串
154
- * @private
155
- * @param {string} str - 字符串
156
- * @returns {string} 转义后的字符串
157
- */
158
- _escapeString(str) {
159
- return str.replace(/'/g, "''");
160
- }
161
-
162
- /**
163
- * 检测主键
164
- * @private
165
- * @param {Object} schema - JSON Schema对象
166
- * @returns {string|null} 主键列名
167
- */
168
- _detectPrimaryKey(schema) {
169
- if (!schema.properties) {
170
- return null;
171
- }
172
-
173
- // 查找名为id或_id的字段
174
- if (schema.properties.id) {
175
- return 'id';
176
- }
177
- if (schema.properties._id) {
178
- return '_id';
179
- }
180
-
181
- return null;
182
- }
183
-
184
- /**
185
- * 生成索引DDL
186
- * @param {string} tableName - 表名
187
- * @param {string} columnName - 列名
188
- * @param {Object} options - 索引选项
189
- * @returns {string} CREATE INDEX语句
190
- */
191
- generateIndex(tableName, columnName, options = {}) {
192
- const indexName = options.name || `idx_${tableName}_${columnName}`;
193
- const unique = options.unique ? 'UNIQUE ' : '';
194
-
195
- return `CREATE ${unique}INDEX \`${indexName}\` ON \`${tableName}\` (\`${columnName}\`);`;
196
- }
197
-
198
- /**
199
- * 静态方法:快速导出
200
- * @static
201
- * @param {string} tableName - 表名
202
- * @param {Object} jsonSchema - JSON Schema对象
203
- * @returns {string} MySQL DDL语句
204
- */
205
- static export(tableName, jsonSchema) {
206
- const exporter = new MySQLExporter();
207
- return exporter.export(tableName, jsonSchema);
208
- }
209
- }
210
-
211
- module.exports = MySQLExporter;
212
-
@@ -1,289 +0,0 @@
1
- /**
2
- * PostgreSQL DDL导出器
3
- *
4
- * 将JSON Schema转换为PostgreSQL CREATE TABLE语句
5
- *
6
- * @module lib/exporters/PostgreSQLExporter
7
- * @version 1.0.0
8
- */
9
-
10
- const TypeConverter = require('../utils/TypeConverter');
11
-
12
- /**
13
- * PostgreSQL导出器类
14
- * @class PostgreSQLExporter
15
- */
16
- class PostgreSQLExporter {
17
- /**
18
- * 构造函数
19
- * @param {Object} options - 配置选项
20
- * @param {string} options.schema - PostgreSQL schema名称(默认public)
21
- */
22
- constructor(options = {}) {
23
- this.options = {
24
- schema: options.schema || 'public',
25
- ...options
26
- };
27
- }
28
-
29
- /**
30
- * 导出为PostgreSQL CREATE TABLE语句
31
- * @param {string} tableName - 表名
32
- * @param {Object} jsonSchema - JSON Schema对象
33
- * @returns {string} PostgreSQL DDL语句
34
- */
35
- export(tableName, jsonSchema) {
36
- if (!tableName || typeof tableName !== 'string') {
37
- throw new Error('Table name is required');
38
- }
39
- if (!jsonSchema || jsonSchema.type !== 'object') {
40
- throw new Error('JSON Schema must be an object type');
41
- }
42
-
43
- const fullTableName = `${this.options.schema}.${tableName}`;
44
- const columns = this._convertProperties(jsonSchema);
45
- const primaryKey = this._detectPrimaryKey(jsonSchema);
46
-
47
- let ddl = `CREATE TABLE ${fullTableName} (\n`;
48
-
49
- // 添加列定义
50
- const columnDefs = columns.map(col => ` ${col}`).join(',\n');
51
- ddl += columnDefs;
52
-
53
- // 添加主键
54
- if (primaryKey) {
55
- ddl += `,\n PRIMARY KEY (${primaryKey})`;
56
- }
57
-
58
- ddl += `\n);`;
59
-
60
- // 添加表注释
61
- if (jsonSchema.description) {
62
- ddl += `\n\nCOMMENT ON TABLE ${fullTableName} IS '${this._escapeString(jsonSchema.description)}';`;
63
- }
64
-
65
- // 添加列注释
66
- const commentDdls = this._generateColumnComments(fullTableName, jsonSchema);
67
- if (commentDdls.length > 0) {
68
- ddl += '\n\n' + commentDdls.join('\n');
69
- }
70
-
71
- return ddl;
72
- }
73
-
74
- /**
75
- * 转换properties为列定义
76
- * @private
77
- * @param {Object} schema - JSON Schema对象
78
- * @returns {Array<string>} 列定义数组
79
- */
80
- _convertProperties(schema) {
81
- if (!schema.properties) {
82
- return [];
83
- }
84
-
85
- const columns = [];
86
- const required = schema.required || [];
87
-
88
- for (const [name, propSchema] of Object.entries(schema.properties)) {
89
- const columnDef = this._convertColumn(name, propSchema, required.includes(name));
90
- columns.push(columnDef);
91
- }
92
-
93
- return columns;
94
- }
95
-
96
- /**
97
- * 转换单个列
98
- * @private
99
- * @param {string} name - 列名
100
- * @param {Object} schema - 属性Schema
101
- * @param {boolean} isRequired - 是否必填
102
- * @returns {string} 列定义字符串
103
- */
104
- _convertColumn(name, schema, isRequired) {
105
- const constraints = TypeConverter.extractConstraints(schema);
106
- const pgType = TypeConverter.toPostgreSQLType(schema.type, constraints);
107
-
108
- let def = `${name} ${pgType}`;
109
-
110
- // NULL约束
111
- if (isRequired) {
112
- def += ' NOT NULL';
113
- }
114
-
115
- // 默认值
116
- if (schema.default !== undefined) {
117
- const defaultValue = this._formatDefaultValue(schema.default, schema.type);
118
- def += ` DEFAULT ${defaultValue}`;
119
- }
120
-
121
- // UNIQUE约束
122
- if (schema.format === 'email' || schema.format === 'uuid') {
123
- // email和uuid通常是唯一的
124
- // def += ' UNIQUE'; // 可选
125
- }
126
-
127
- // CHECK约束
128
- const checkConstraints = this._generateCheckConstraints(name, schema);
129
- if (checkConstraints.length > 0) {
130
- def += ' ' + checkConstraints.join(' ');
131
- }
132
-
133
- return def;
134
- }
135
-
136
- /**
137
- * 生成CHECK约束
138
- * @private
139
- * @param {string} columnName - 列名
140
- * @param {Object} schema - 属性Schema
141
- * @returns {Array<string>} CHECK约束数组
142
- */
143
- _generateCheckConstraints(columnName, schema) {
144
- const checks = [];
145
-
146
- // 字符串长度
147
- if (schema.minLength !== undefined || schema.maxLength !== undefined) {
148
- if (schema.minLength !== undefined && schema.maxLength !== undefined) {
149
- checks.push(`CHECK (LENGTH(${columnName}) BETWEEN ${schema.minLength} AND ${schema.maxLength})`);
150
- } else if (schema.minLength !== undefined) {
151
- checks.push(`CHECK (LENGTH(${columnName}) >= ${schema.minLength})`);
152
- } else {
153
- checks.push(`CHECK (LENGTH(${columnName}) <= ${schema.maxLength})`);
154
- }
155
- }
156
-
157
- // 数值范围
158
- if (schema.minimum !== undefined || schema.maximum !== undefined) {
159
- if (schema.minimum !== undefined && schema.maximum !== undefined) {
160
- checks.push(`CHECK (${columnName} BETWEEN ${schema.minimum} AND ${schema.maximum})`);
161
- } else if (schema.minimum !== undefined) {
162
- checks.push(`CHECK (${columnName} >= ${schema.minimum})`);
163
- } else {
164
- checks.push(`CHECK (${columnName} <= ${schema.maximum})`);
165
- }
166
- }
167
-
168
- // 枚举
169
- if (schema.enum) {
170
- const values = schema.enum.map(v => `'${this._escapeString(v)}'`).join(', ');
171
- checks.push(`CHECK (${columnName} IN (${values}))`);
172
- }
173
-
174
- return checks;
175
- }
176
-
177
- /**
178
- * 格式化默认值
179
- * @private
180
- * @param {*} value - 默认值
181
- * @param {string} type - 类型
182
- * @returns {string} 格式化后的默认值
183
- */
184
- _formatDefaultValue(value, type) {
185
- if (value === null) {
186
- return 'NULL';
187
- }
188
-
189
- if (type === 'string') {
190
- return `'${this._escapeString(value)}'`;
191
- }
192
-
193
- if (type === 'boolean') {
194
- return value ? 'TRUE' : 'FALSE';
195
- }
196
-
197
- if (type === 'object' || type === 'array') {
198
- return `'${JSON.stringify(value)}'::JSONB`;
199
- }
200
-
201
- return value.toString();
202
- }
203
-
204
- /**
205
- * 转义字符串
206
- * @private
207
- * @param {string} str - 字符串
208
- * @returns {string} 转义后的字符串
209
- */
210
- _escapeString(str) {
211
- return str.replace(/'/g, "''");
212
- }
213
-
214
- /**
215
- * 检测主键
216
- * @private
217
- * @param {Object} schema - JSON Schema对象
218
- * @returns {string|null} 主键列名
219
- */
220
- _detectPrimaryKey(schema) {
221
- if (!schema.properties) {
222
- return null;
223
- }
224
-
225
- // 查找名为id或_id的字段
226
- if (schema.properties.id) {
227
- return 'id';
228
- }
229
- if (schema.properties._id) {
230
- return '_id';
231
- }
232
-
233
- return null;
234
- }
235
-
236
- /**
237
- * 生成列注释
238
- * @private
239
- * @param {string} tableName - 表名
240
- * @param {Object} schema - JSON Schema对象
241
- * @returns {Array<string>} COMMENT语句数组
242
- */
243
- _generateColumnComments(tableName, schema) {
244
- if (!schema.properties) {
245
- return [];
246
- }
247
-
248
- const comments = [];
249
-
250
- for (const [name, propSchema] of Object.entries(schema.properties)) {
251
- if (propSchema.description) {
252
- comments.push(`COMMENT ON COLUMN ${tableName}.${name} IS '${this._escapeString(propSchema.description)}';`);
253
- }
254
- }
255
-
256
- return comments;
257
- }
258
-
259
- /**
260
- * 生成索引DDL
261
- * @param {string} tableName - 表名
262
- * @param {string} columnName - 列名
263
- * @param {Object} options - 索引选项
264
- * @returns {string} CREATE INDEX语句
265
- */
266
- generateIndex(tableName, columnName, options = {}) {
267
- const fullTableName = `${this.options.schema}.${tableName}`;
268
- const indexName = options.name || `idx_${tableName}_${columnName}`;
269
- const unique = options.unique ? 'UNIQUE ' : '';
270
- const method = options.method || 'btree'; // btree, hash, gin, gist
271
-
272
- return `CREATE ${unique}INDEX ${indexName} ON ${fullTableName} USING ${method} (${columnName});`;
273
- }
274
-
275
- /**
276
- * 静态方法:快速导出
277
- * @static
278
- * @param {string} tableName - 表名
279
- * @param {Object} jsonSchema - JSON Schema对象
280
- * @returns {string} PostgreSQL DDL语句
281
- */
282
- static export(tableName, jsonSchema) {
283
- const exporter = new PostgreSQLExporter();
284
- return exporter.export(tableName, jsonSchema);
285
- }
286
- }
287
-
288
- module.exports = PostgreSQLExporter;
289
-
@@ -1,24 +0,0 @@
1
- /**
2
- * Exporters - 导出器统一导出
3
- * @module lib/exporters
4
- */
5
-
6
- const MongoDBExporter = require('./MongoDBExporter');
7
- const MySQLExporter = require('./MySQLExporter');
8
- const PostgreSQLExporter = require('./PostgreSQLExporter');
9
- const MarkdownExporter = require('./MarkdownExporter');
10
-
11
- module.exports = {
12
- MongoDBExporter,
13
- MySQLExporter,
14
- PostgreSQLExporter,
15
- MarkdownExporter,
16
-
17
- // 别名
18
- MongoDB: MongoDBExporter,
19
- MySQL: MySQLExporter,
20
- PostgreSQL: PostgreSQLExporter,
21
- Postgres: PostgreSQLExporter,
22
- Markdown: MarkdownExporter
23
- };
24
-
@@ -1,8 +0,0 @@
1
- module.exports = {
2
- 'zh-CN': require('./zh-CN'),
3
- 'en-US': require('./en-US'),
4
- 'ja-JP': require('./ja-JP'),
5
- 'es-ES': require('./es-ES'),
6
- 'fr-FR': require('./fr-FR')
7
- };
8
-
@@ -1,174 +0,0 @@
1
- /**
2
- * 带内存管理的 LRU 缓存实现
3
- * 用于安全缓存语言包消息,防止内存泄漏
4
- *
5
- * @module lib/utils/LRUCache
6
- * @version 2.2.1
7
- */
8
-
9
- /**
10
- * LRU (Least Recently Used) 缓存
11
- * 自动清理最少使用的条目,确保内存占用可控
12
- */
13
- class LRUCache {
14
- /**
15
- * 创建 LRU 缓存实例
16
- * @param {Object} options - 配置选项
17
- * @param {number} [options.maxSize=10] - 最大缓存数量
18
- * @param {boolean} [options.enableStats=false] - 是否启用统计
19
- */
20
- constructor(options = {}) {
21
- this.maxSize = options.maxSize || 10;
22
- this.enableStats = options.enableStats || false;
23
- this.cache = new Map();
24
-
25
- if (this.enableStats) {
26
- this.stats = {
27
- hits: 0,
28
- misses: 0,
29
- evictions: 0,
30
- sets: 0
31
- };
32
- }
33
- }
34
-
35
- /**
36
- * 获取缓存值
37
- * @param {string} key - 键
38
- * @returns {*} 缓存的值,不存在则返回 undefined
39
- */
40
- get(key) {
41
- if (!this.cache.has(key)) {
42
- if (this.enableStats) this.stats.misses++;
43
- return undefined;
44
- }
45
-
46
- if (this.enableStats) this.stats.hits++;
47
-
48
- // LRU: 移到最后(标记为最近使用)
49
- const value = this.cache.get(key);
50
- this.cache.delete(key);
51
- this.cache.set(key, value);
52
-
53
- return value;
54
- }
55
-
56
- /**
57
- * 设置缓存值
58
- * @param {string} key - 键
59
- * @param {*} value - 值
60
- */
61
- set(key, value) {
62
- if (this.enableStats) this.stats.sets++;
63
-
64
- // 如果已存在,先删除(更新顺序)
65
- if (this.cache.has(key)) {
66
- this.cache.delete(key);
67
- }
68
-
69
- // 如果超过容量,删除最旧的(最少使用)
70
- if (this.cache.size >= this.maxSize) {
71
- const firstKey = this.cache.keys().next().value;
72
- this.cache.delete(firstKey);
73
-
74
- if (this.enableStats) this.stats.evictions++;
75
-
76
- // 开发环境警告
77
- if (process.env.NODE_ENV === 'development') {
78
- console.warn(`[LRUCache] Evicted key: ${firstKey} (cache full: ${this.maxSize})`);
79
- }
80
- }
81
-
82
- this.cache.set(key, value);
83
- }
84
-
85
- /**
86
- * 检查键是否存在
87
- * @param {string} key - 键
88
- * @returns {boolean} 是否存在
89
- */
90
- has(key) {
91
- return this.cache.has(key);
92
- }
93
-
94
- /**
95
- * 删除指定键
96
- * @param {string} key - 键
97
- * @returns {boolean} 是否删除成功
98
- */
99
- delete(key) {
100
- return this.cache.delete(key);
101
- }
102
-
103
- /**
104
- * 清空所有缓存
105
- */
106
- clear() {
107
- this.cache.clear();
108
-
109
- if (this.enableStats) {
110
- this.stats = {
111
- hits: 0,
112
- misses: 0,
113
- evictions: 0,
114
- sets: 0
115
- };
116
- }
117
- }
118
-
119
- /**
120
- * 获取当前缓存大小
121
- * @returns {number} 缓存条目数量
122
- */
123
- get size() {
124
- return this.cache.size;
125
- }
126
-
127
- /**
128
- * 获取所有键
129
- * @returns {Array<string>} 键数组
130
- */
131
- keys() {
132
- return Array.from(this.cache.keys());
133
- }
134
-
135
- /**
136
- * 获取缓存统计信息
137
- * @returns {Object} 统计信息
138
- */
139
- getStats() {
140
- if (!this.enableStats) {
141
- return { message: 'Stats not enabled. Set enableStats: true in constructor.' };
142
- }
143
-
144
- const total = this.stats.hits + this.stats.misses;
145
- const hitRate = total > 0 ? (this.stats.hits / total * 100).toFixed(2) : 0;
146
-
147
- return {
148
- hits: this.stats.hits,
149
- misses: this.stats.misses,
150
- evictions: this.stats.evictions,
151
- sets: this.stats.sets,
152
- hitRate: `${hitRate}%`,
153
- size: this.cache.size,
154
- maxSize: this.maxSize,
155
- efficiency: hitRate >= 80 ? '优秀' : hitRate >= 60 ? '良好' : '需优化'
156
- };
157
- }
158
-
159
- /**
160
- * 重置统计信息
161
- */
162
- resetStats() {
163
- if (this.enableStats) {
164
- this.stats = {
165
- hits: 0,
166
- misses: 0,
167
- evictions: 0,
168
- sets: 0
169
- };
170
- }
171
- }
172
- }
173
-
174
- module.exports = LRUCache;