schema-dsl 1.2.5 → 2.0.1

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 (243) hide show
  1. package/CHANGELOG.md +130 -238
  2. package/LICENSE +21 -21
  3. package/README.md +628 -2486
  4. package/dist/DslBuilder-BIgQOAXp.d.ts +343 -0
  5. package/dist/DslBuilder-CjHTucNQ.d.cts +343 -0
  6. package/dist/Validator-CllRdrY0.d.ts +192 -0
  7. package/dist/Validator-D6okG9tr.d.cts +192 -0
  8. package/dist/index.cjs +6640 -0
  9. package/dist/index.d.cts +1151 -0
  10. package/dist/index.d.ts +1151 -0
  11. package/dist/index.js +6574 -0
  12. package/dist/plugin-CIKtTMtS.d.cts +246 -0
  13. package/dist/plugin-CIKtTMtS.d.ts +246 -0
  14. package/dist/plugins/custom-format.cjs +3818 -0
  15. package/dist/plugins/custom-format.d.cts +12 -0
  16. package/dist/plugins/custom-format.d.ts +12 -0
  17. package/dist/plugins/custom-format.js +3788 -0
  18. package/dist/plugins/custom-type-example.cjs +3811 -0
  19. package/dist/plugins/custom-type-example.d.cts +8 -0
  20. package/dist/plugins/custom-type-example.d.ts +8 -0
  21. package/dist/plugins/custom-type-example.js +3781 -0
  22. package/dist/plugins/custom-validator.cjs +144 -0
  23. package/dist/plugins/custom-validator.d.cts +10 -0
  24. package/dist/plugins/custom-validator.d.ts +10 -0
  25. package/dist/plugins/custom-validator.js +119 -0
  26. package/docs/FEATURE-INDEX.md +553 -519
  27. package/docs/add-custom-locale.md +496 -483
  28. package/docs/add-keyword.md +24 -0
  29. package/docs/api-reference.md +1047 -805
  30. package/docs/api.md +13 -0
  31. package/docs/best-practices-project-structure.md +417 -408
  32. package/docs/best-practices.md +712 -672
  33. package/docs/cache-manager.md +344 -336
  34. package/docs/compile.md +45 -0
  35. package/docs/conditional-api.md +1307 -1278
  36. package/docs/custom-extensions-guide.md +339 -411
  37. package/docs/design-philosophy.md +606 -601
  38. package/docs/doc-index.md +324 -0
  39. package/docs/dsl-syntax.md +714 -664
  40. package/docs/dynamic-locale.md +608 -598
  41. package/docs/enum.md +482 -475
  42. package/docs/error-handling.md +1975 -1966
  43. package/docs/export-guide.md +501 -462
  44. package/docs/export-limitations.md +567 -551
  45. package/docs/faq.md +596 -577
  46. package/docs/frontend-i18n-guide.md +307 -293
  47. package/docs/i18n-user-guide.md +487 -474
  48. package/docs/i18n.md +476 -457
  49. package/docs/index.md +48 -0
  50. package/docs/json-schema-basics.md +40 -0
  51. package/docs/label-vs-description.md +271 -262
  52. package/docs/markdown-exporter.md +406 -397
  53. package/docs/mongodb-exporter.md +302 -295
  54. package/docs/multi-language.md +26 -0
  55. package/docs/multi-type-support.md +322 -329
  56. package/docs/mysql-exporter.md +280 -273
  57. package/docs/number-operators.md +449 -442
  58. package/docs/optional-marker-guide.md +326 -321
  59. package/docs/performance-guide.md +49 -0
  60. package/docs/plugin-system.md +381 -542
  61. package/docs/plugin-type-registration.md +34 -0
  62. package/docs/postgresql-exporter.md +311 -304
  63. package/docs/public/favicon.svg +5 -0
  64. package/docs/quick-start.md +435 -761
  65. package/docs/runtime-locale-support.md +532 -521
  66. package/docs/schema-helper.md +345 -340
  67. package/docs/schema-utils-advanced-issues.md +23 -0
  68. package/docs/schema-utils-best-practices.md +20 -0
  69. package/docs/schema-utils-chaining.md +150 -143
  70. package/docs/schema-utils.md +524 -490
  71. package/docs/security-checklist.md +20 -0
  72. package/docs/string-extensions.md +488 -480
  73. package/docs/troubleshooting.md +486 -471
  74. package/docs/type-converter.md +310 -319
  75. package/docs/type-reference.md +242 -219
  76. package/docs/typescript-guide.md +584 -573
  77. package/docs/union-type-guide.md +157 -147
  78. package/docs/union-types.md +284 -277
  79. package/docs/validate-async.md +491 -480
  80. package/docs/validate-batch.md +49 -0
  81. package/docs/validate-dsl-object-support.md +578 -573
  82. package/docs/validate.md +506 -486
  83. package/docs/validation-guide.md +502 -484
  84. package/docs/validator.md +39 -0
  85. package/package.json +131 -73
  86. package/plugins/custom-format.cjs +8 -0
  87. package/plugins/custom-type-example.cjs +8 -0
  88. package/plugins/custom-validator.cjs +8 -0
  89. package/src/adapters/DslAdapter.ts +111 -0
  90. package/src/adapters/index.ts +1 -0
  91. package/src/config/constants.ts +83 -0
  92. package/src/config/index.ts +2 -0
  93. package/src/config/patterns.ts +77 -0
  94. package/src/core/CacheManager.ts +169 -0
  95. package/src/core/ConditionalBuilder.ts +382 -0
  96. package/src/core/ConditionalRuntime.ts +28 -0
  97. package/src/core/ConditionalValidator.ts +255 -0
  98. package/src/core/DslBuilder.ts +687 -0
  99. package/src/core/ErrorCodes.ts +38 -0
  100. package/src/core/ErrorFormatter.ts +271 -0
  101. package/src/core/JSONSchemaCore.ts +65 -0
  102. package/src/core/Locale.ts +187 -0
  103. package/src/core/MessageTemplate.ts +42 -0
  104. package/src/core/ObjectDslBuilder.ts +64 -0
  105. package/src/core/PluginManager.ts +326 -0
  106. package/src/core/StringExtensions.ts +140 -0
  107. package/src/core/TemplateEngine.ts +44 -0
  108. package/src/core/Validator.ts +448 -0
  109. package/src/errors/I18nError.ts +159 -0
  110. package/src/errors/ValidationError.ts +105 -0
  111. package/src/exporters/BaseExporter.ts +60 -0
  112. package/src/exporters/MarkdownExporter.ts +305 -0
  113. package/src/exporters/MongoDBExporter.ts +126 -0
  114. package/src/exporters/MySQLExporter.ts +156 -0
  115. package/src/exporters/PostgreSQLExporter.ts +222 -0
  116. package/src/exporters/index.ts +18 -0
  117. package/src/index.ts +651 -0
  118. package/{lib/locales/en-US.js → src/locales/en-US.ts} +160 -176
  119. package/{lib/locales/es-ES.js → src/locales/es-ES.ts} +160 -113
  120. package/{lib/locales/fr-FR.js → src/locales/fr-FR.ts} +160 -113
  121. package/src/locales/index.ts +103 -0
  122. package/{lib/locales/ja-JP.js → src/locales/ja-JP.ts} +160 -118
  123. package/src/locales/types.ts +156 -0
  124. package/{lib/locales/zh-CN.js → src/locales/zh-CN.ts} +160 -177
  125. package/src/parser/ConstraintParser.ts +101 -0
  126. package/src/parser/DslParser.ts +470 -0
  127. package/src/parser/SchemaCompiler.ts +66 -0
  128. package/src/parser/TypeRegistry.ts +250 -0
  129. package/src/parser/index.ts +6 -0
  130. package/src/plugins/custom-format.ts +124 -0
  131. package/src/plugins/custom-type-example.ts +106 -0
  132. package/src/plugins/custom-validator.ts +138 -0
  133. package/src/types/conditional.ts +28 -0
  134. package/src/types/config.ts +59 -0
  135. package/src/types/dsl.ts +131 -0
  136. package/src/types/error.ts +60 -0
  137. package/src/types/index.ts +17 -0
  138. package/src/types/infer.ts +128 -0
  139. package/src/types/plugin.ts +58 -0
  140. package/src/types/safe-regex.d.ts +9 -0
  141. package/src/types/schema.ts +66 -0
  142. package/src/types/validate.ts +71 -0
  143. package/src/utils/SchemaHelper.ts +196 -0
  144. package/src/utils/SchemaUtils.ts +365 -0
  145. package/src/utils/TypeConverter.ts +215 -0
  146. package/src/utils/index.ts +10 -0
  147. package/src/validators/CustomKeywords.ts +477 -0
  148. package/.eslintignore +0 -11
  149. package/.eslintrc.json +0 -27
  150. package/CONTRIBUTING.md +0 -368
  151. package/STATUS.md +0 -491
  152. package/changelogs/v1.0.0.md +0 -328
  153. package/changelogs/v1.0.9.md +0 -367
  154. package/changelogs/v1.1.0.md +0 -389
  155. package/changelogs/v1.1.1.md +0 -308
  156. package/changelogs/v1.1.2.md +0 -183
  157. package/changelogs/v1.1.3.md +0 -161
  158. package/changelogs/v1.1.4.md +0 -432
  159. package/changelogs/v1.1.5.md +0 -493
  160. package/changelogs/v1.1.6.md +0 -211
  161. package/changelogs/v1.1.8.md +0 -376
  162. package/changelogs/v1.2.3.md +0 -124
  163. package/docs/INDEX.md +0 -252
  164. package/docs/issues-resolved-summary.md +0 -196
  165. package/docs/performance-benchmark-report.md +0 -179
  166. package/docs/performance-quick-reference.md +0 -123
  167. package/docs/user-questions-answered.md +0 -353
  168. package/docs/validation-rules-v1.0.2.md +0 -1608
  169. package/examples/README.md +0 -81
  170. package/examples/array-dsl-example.js +0 -227
  171. package/examples/conditional-example.js +0 -288
  172. package/examples/conditional-non-object.js +0 -129
  173. package/examples/conditional-validate-example.js +0 -321
  174. package/examples/custom-extension.js +0 -85
  175. package/examples/dsl-match-example.js +0 -74
  176. package/examples/dsl-style.js +0 -118
  177. package/examples/dynamic-locale-configuration.js +0 -348
  178. package/examples/dynamic-locale-example.js +0 -287
  179. package/examples/enum.examples.js +0 -324
  180. package/examples/export-demo.js +0 -130
  181. package/examples/express-integration.js +0 -376
  182. package/examples/i18n-error-handling-complete.js +0 -381
  183. package/examples/i18n-error-handling-quickstart.md +0 -0
  184. package/examples/i18n-error.examples.js +0 -181
  185. package/examples/i18n-full-demo.js +0 -301
  186. package/examples/i18n-memory-safety.examples.js +0 -268
  187. package/examples/markdown-export.js +0 -71
  188. package/examples/middleware-usage.js +0 -93
  189. package/examples/new-features-comparison.js +0 -315
  190. package/examples/password-reset/README.md +0 -153
  191. package/examples/password-reset/schema.js +0 -26
  192. package/examples/password-reset/test.js +0 -101
  193. package/examples/plugin-system.examples.js +0 -205
  194. package/examples/schema-utils-chaining.examples.js +0 -250
  195. package/examples/simple-example.js +0 -122
  196. package/examples/slug.examples.js +0 -179
  197. package/examples/string-extensions.js +0 -297
  198. package/examples/union-type-example.js +0 -127
  199. package/examples/union-types-example.js +0 -77
  200. package/examples/user-registration/README.md +0 -156
  201. package/examples/user-registration/routes.js +0 -92
  202. package/examples/user-registration/schema.js +0 -150
  203. package/examples/user-registration/server.js +0 -74
  204. package/index.d.ts +0 -3658
  205. package/index.js +0 -475
  206. package/index.mjs +0 -60
  207. package/lib/adapters/DslAdapter.js +0 -995
  208. package/lib/adapters/index.js +0 -20
  209. package/lib/config/constants.js +0 -286
  210. package/lib/config/patterns/common.js +0 -47
  211. package/lib/config/patterns/creditCard.js +0 -9
  212. package/lib/config/patterns/idCard.js +0 -9
  213. package/lib/config/patterns/index.js +0 -9
  214. package/lib/config/patterns/licensePlate.js +0 -4
  215. package/lib/config/patterns/passport.js +0 -4
  216. package/lib/config/patterns/phone.js +0 -9
  217. package/lib/config/patterns/postalCode.js +0 -5
  218. package/lib/core/CacheManager.js +0 -376
  219. package/lib/core/ConditionalBuilder.js +0 -503
  220. package/lib/core/DslBuilder.js +0 -1589
  221. package/lib/core/ErrorCodes.js +0 -233
  222. package/lib/core/ErrorFormatter.js +0 -445
  223. package/lib/core/JSONSchemaCore.js +0 -347
  224. package/lib/core/Locale.js +0 -130
  225. package/lib/core/MessageTemplate.js +0 -98
  226. package/lib/core/PluginManager.js +0 -448
  227. package/lib/core/StringExtensions.js +0 -240
  228. package/lib/core/Validator.js +0 -654
  229. package/lib/errors/I18nError.js +0 -328
  230. package/lib/errors/ValidationError.js +0 -191
  231. package/lib/exporters/MarkdownExporter.js +0 -420
  232. package/lib/exporters/MongoDBExporter.js +0 -162
  233. package/lib/exporters/MySQLExporter.js +0 -212
  234. package/lib/exporters/PostgreSQLExporter.js +0 -289
  235. package/lib/exporters/index.js +0 -24
  236. package/lib/locales/index.js +0 -8
  237. package/lib/utils/LRUCache.js +0 -174
  238. package/lib/utils/SchemaHelper.js +0 -240
  239. package/lib/utils/SchemaUtils.js +0 -445
  240. package/lib/utils/TypeConverter.js +0 -245
  241. package/lib/utils/index.js +0 -13
  242. package/lib/validators/CustomKeywords.js +0 -616
  243. 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;