fdb2 1.0.6 → 1.0.8

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 (193) hide show
  1. package/.vscodeignore +45 -0
  2. package/README.md +24 -85
  3. package/dist/package.json +115 -0
  4. package/dist/pnpm-lock.yaml +7447 -0
  5. package/dist/public/explorer.css +244 -111
  6. package/dist/public/explorer.js +523 -278
  7. package/dist/scripts/preinstall.js +112 -0
  8. package/dist/server/index.d.ts.map +1 -1
  9. package/dist/server/index.js +4 -9
  10. package/dist/server/index.js.map +1 -1
  11. package/dist/server/index.ts +5 -10
  12. package/dist/server/service/connection.service.d.ts.map +1 -1
  13. package/dist/server/service/connection.service.js +1 -0
  14. package/dist/server/service/connection.service.js.map +1 -1
  15. package/dist/server/service/connection.service.ts +1 -0
  16. package/dist/server/service/database/base.service.d.ts +4 -0
  17. package/dist/server/service/database/base.service.d.ts.map +1 -1
  18. package/dist/server/service/database/base.service.js +3 -3
  19. package/dist/server/service/database/base.service.js.map +1 -1
  20. package/dist/server/service/database/base.service.ts +8 -3
  21. package/dist/server/service/database/cockroachdb.service.d.ts +5 -0
  22. package/dist/server/service/database/cockroachdb.service.d.ts.map +1 -1
  23. package/dist/server/service/database/cockroachdb.service.js +112 -0
  24. package/dist/server/service/database/cockroachdb.service.js.map +1 -1
  25. package/dist/server/service/database/cockroachdb.service.ts +123 -0
  26. package/dist/server/service/database/database.service.d.ts +4 -0
  27. package/dist/server/service/database/database.service.d.ts.map +1 -1
  28. package/dist/server/service/database/database.service.js +8 -0
  29. package/dist/server/service/database/database.service.js.map +1 -1
  30. package/dist/server/service/database/database.service.ts +9 -0
  31. package/dist/server/service/database/mongodb.service.d.ts +6 -0
  32. package/dist/server/service/database/mongodb.service.d.ts.map +1 -1
  33. package/dist/server/service/database/mongodb.service.js +8 -0
  34. package/dist/server/service/database/mongodb.service.js.map +1 -1
  35. package/dist/server/service/database/mongodb.service.ts +9 -0
  36. package/dist/server/service/database/mssql.service.d.ts +4 -0
  37. package/dist/server/service/database/mssql.service.d.ts.map +1 -1
  38. package/dist/server/service/database/mssql.service.js +105 -0
  39. package/dist/server/service/database/mssql.service.js.map +1 -1
  40. package/dist/server/service/database/mssql.service.ts +118 -0
  41. package/dist/server/service/database/mysql.service.d.ts +4 -0
  42. package/dist/server/service/database/mysql.service.d.ts.map +1 -1
  43. package/dist/server/service/database/mysql.service.js +116 -0
  44. package/dist/server/service/database/mysql.service.js.map +1 -1
  45. package/dist/server/service/database/mysql.service.ts +130 -0
  46. package/dist/server/service/database/oracle.service.d.ts +4 -0
  47. package/dist/server/service/database/oracle.service.d.ts.map +1 -1
  48. package/dist/server/service/database/oracle.service.js +114 -0
  49. package/dist/server/service/database/oracle.service.js.map +1 -1
  50. package/dist/server/service/database/oracle.service.ts +128 -0
  51. package/dist/server/service/database/postgres.service.d.ts +4 -0
  52. package/dist/server/service/database/postgres.service.d.ts.map +1 -1
  53. package/dist/server/service/database/postgres.service.js +120 -0
  54. package/dist/server/service/database/postgres.service.js.map +1 -1
  55. package/dist/server/service/database/postgres.service.ts +131 -0
  56. package/dist/server/service/database/sap.service.d.ts +4 -0
  57. package/dist/server/service/database/sap.service.d.ts.map +1 -1
  58. package/dist/server/service/database/sap.service.js +107 -0
  59. package/dist/server/service/database/sap.service.js.map +1 -1
  60. package/dist/server/service/database/sap.service.ts +120 -0
  61. package/dist/server/service/database/sqlite.service.d.ts +5 -0
  62. package/dist/server/service/database/sqlite.service.d.ts.map +1 -1
  63. package/dist/server/service/database/sqlite.service.js +133 -0
  64. package/dist/server/service/database/sqlite.service.js.map +1 -1
  65. package/dist/server/service/database/sqlite.service.ts +150 -0
  66. package/fdb2.server.pid +1 -0
  67. package/package.json +18 -9
  68. package/packages/vscode/.vscodeignore +44 -0
  69. package/packages/vscode/README.md +62 -0
  70. package/packages/vscode/out/database-services/base.service.js +236 -0
  71. package/packages/vscode/out/database-services/base.service.js.map +1 -0
  72. package/packages/vscode/out/database-services/cockroachdb.service.js +634 -0
  73. package/packages/vscode/out/database-services/cockroachdb.service.js.map +1 -0
  74. package/packages/vscode/out/database-services/connection.service.js +346 -0
  75. package/packages/vscode/out/database-services/connection.service.js.map +1 -0
  76. package/packages/vscode/out/database-services/database.service.js +571 -0
  77. package/packages/vscode/out/database-services/database.service.js.map +1 -0
  78. package/packages/vscode/out/database-services/index.js +18 -0
  79. package/packages/vscode/out/database-services/index.js.map +1 -0
  80. package/packages/vscode/out/database-services/model/connection.entity.js +11 -0
  81. package/packages/vscode/out/database-services/model/connection.entity.js.map +1 -0
  82. package/packages/vscode/out/database-services/model/database.entity.js +35 -0
  83. package/packages/vscode/out/database-services/model/database.entity.js.map +1 -0
  84. package/packages/vscode/out/database-services/mongodb.service.js +458 -0
  85. package/packages/vscode/out/database-services/mongodb.service.js.map +1 -0
  86. package/packages/vscode/out/database-services/mssql.service.js +694 -0
  87. package/packages/vscode/out/database-services/mssql.service.js.map +1 -0
  88. package/packages/vscode/out/database-services/mysql.service.js +735 -0
  89. package/packages/vscode/out/database-services/mysql.service.js.map +1 -0
  90. package/packages/vscode/out/database-services/oracle.service.js +787 -0
  91. package/packages/vscode/out/database-services/oracle.service.js.map +1 -0
  92. package/packages/vscode/out/database-services/postgres.service.js +696 -0
  93. package/packages/vscode/out/database-services/postgres.service.js.map +1 -0
  94. package/packages/vscode/out/database-services/sap.service.js +695 -0
  95. package/packages/vscode/out/database-services/sap.service.js.map +1 -0
  96. package/packages/vscode/out/database-services/sqlite.service.js +532 -0
  97. package/packages/vscode/out/database-services/sqlite.service.js.map +1 -0
  98. package/packages/vscode/out/extension.js +93 -0
  99. package/packages/vscode/out/extension.js.map +1 -0
  100. package/packages/vscode/out/provider/DatabaseTreeProvider.js +159 -0
  101. package/packages/vscode/out/provider/DatabaseTreeProvider.js.map +1 -0
  102. package/packages/vscode/out/provider/WebViewProvider.js +259 -0
  103. package/packages/vscode/out/provider/WebViewProvider.js.map +1 -0
  104. package/packages/vscode/out/service/ConnectionManager.js +105 -0
  105. package/packages/vscode/out/service/ConnectionManager.js.map +1 -0
  106. package/packages/vscode/out/service/DatabaseServiceBridge.js +395 -0
  107. package/packages/vscode/out/service/DatabaseServiceBridge.js.map +1 -0
  108. package/packages/vscode/out/typings/connection.js +3 -0
  109. package/packages/vscode/out/typings/connection.js.map +1 -0
  110. package/packages/vscode/package.json +142 -0
  111. package/packages/vscode/resources/icon.svg +5 -0
  112. package/packages/vscode/resources/webview/_plugin-vue_export-helper.js +6529 -0
  113. package/packages/vscode/resources/webview/_plugin-vue_export-helper.js.map +1 -0
  114. package/packages/vscode/resources/webview/connection.css +69 -0
  115. package/packages/vscode/resources/webview/connection.js +228 -0
  116. package/packages/vscode/resources/webview/connection.js.map +1 -0
  117. package/packages/vscode/resources/webview/database.css +259 -0
  118. package/packages/vscode/resources/webview/database.js +275 -0
  119. package/packages/vscode/resources/webview/database.js.map +1 -0
  120. package/packages/vscode/resources/webview/favicon.ico +0 -0
  121. package/packages/vscode/resources/webview/index.html +9 -0
  122. package/packages/vscode/resources/webview/modules/header.tpl +14 -0
  123. package/packages/vscode/resources/webview/modules/initial_state.tpl +55 -0
  124. package/packages/vscode/resources/webview/query.css +162 -0
  125. package/packages/vscode/resources/webview/query.js +198 -0
  126. package/packages/vscode/resources/webview/query.js.map +1 -0
  127. package/packages/vscode/src/database-services/base.service.js.map +1 -0
  128. package/packages/vscode/src/database-services/base.service.ts +363 -0
  129. package/packages/vscode/src/database-services/cockroachdb.service.js.map +1 -0
  130. package/packages/vscode/src/database-services/cockroachdb.service.ts +659 -0
  131. package/packages/vscode/src/database-services/connection.service.ts +341 -0
  132. package/packages/vscode/src/database-services/database.service.ts +630 -0
  133. package/packages/vscode/src/database-services/index.ts +7 -0
  134. package/packages/vscode/src/database-services/model/connection.entity.js +11 -0
  135. package/packages/vscode/src/database-services/model/connection.entity.js.map +1 -0
  136. package/packages/vscode/src/database-services/model/connection.entity.ts +66 -0
  137. package/packages/vscode/src/database-services/model/database.entity.js +35 -0
  138. package/packages/vscode/src/database-services/model/database.entity.js.map +1 -0
  139. package/packages/vscode/src/database-services/model/database.entity.ts +246 -0
  140. package/packages/vscode/src/database-services/mongodb.service.js.map +1 -0
  141. package/packages/vscode/src/database-services/mongodb.service.ts +454 -0
  142. package/packages/vscode/src/database-services/mssql.service.js.map +1 -0
  143. package/packages/vscode/src/database-services/mssql.service.ts +723 -0
  144. package/packages/vscode/src/database-services/mysql.service.js.map +1 -0
  145. package/packages/vscode/src/database-services/mysql.service.ts +761 -0
  146. package/packages/vscode/src/database-services/oracle.service.js.map +1 -0
  147. package/packages/vscode/src/database-services/oracle.service.ts +832 -0
  148. package/packages/vscode/src/database-services/postgres.service.js.map +1 -0
  149. package/packages/vscode/src/database-services/postgres.service.ts +741 -0
  150. package/packages/vscode/src/database-services/sap.service.js.map +1 -0
  151. package/packages/vscode/src/database-services/sap.service.ts +713 -0
  152. package/packages/vscode/src/database-services/sqlite.service.js.map +1 -0
  153. package/packages/vscode/src/database-services/sqlite.service.ts +559 -0
  154. package/packages/vscode/src/extension.ts +76 -0
  155. package/packages/vscode/src/provider/DatabaseTreeProvider.ts +167 -0
  156. package/packages/vscode/src/provider/WebViewProvider.ts +277 -0
  157. package/packages/vscode/src/service/DatabaseServiceBridge.ts +414 -0
  158. package/packages/vscode/src/typings/connection.ts +90 -0
  159. package/packages/vscode/tsconfig.json +21 -0
  160. package/public/fdb2.png +0 -0
  161. package/server/backups/db_ai_breakout_2026-03-11T08-38-48-677Z.sql +0 -0
  162. package/server/index.ts +5 -10
  163. package/server/model/connection.entity.js +11 -0
  164. package/server/model/connection.entity.js.map +1 -0
  165. package/server/model/database.entity.js +35 -0
  166. package/server/model/database.entity.js.map +1 -0
  167. package/server/service/connection.service.ts +1 -0
  168. package/server/service/database/base.service.ts +8 -3
  169. package/server/service/database/cockroachdb.service.ts +123 -0
  170. package/server/service/database/database.service.ts +9 -0
  171. package/server/service/database/mongodb.service.ts +9 -0
  172. package/server/service/database/mssql.service.ts +118 -0
  173. package/server/service/database/mysql.service.ts +130 -0
  174. package/server/service/database/oracle.service.ts +128 -0
  175. package/server/service/database/postgres.service.ts +131 -0
  176. package/server/service/database/sap.service.ts +120 -0
  177. package/server/service/database/sqlite.service.ts +150 -0
  178. package/server/tsconfig.json +20 -0
  179. package/src/components/connection-editor/index.vue +0 -1
  180. package/src/platform/database/components/db-tools.vue +414 -174
  181. package/src/platform/database/components/table-detail.vue +3 -2
  182. package/src/platform/database/components/table-editor.vue +245 -18
  183. package/src/platform/vscode/bridge.ts +121 -0
  184. package/src/platform/vscode/components/ConnectionPanel.vue +272 -0
  185. package/src/platform/vscode/components/DatabasePanel.vue +532 -0
  186. package/src/platform/vscode/components/QueryPanel.vue +371 -0
  187. package/src/platform/vscode/entry/connection.ts +13 -0
  188. package/src/platform/vscode/entry/database.ts +13 -0
  189. package/src/platform/vscode/entry/query.ts +13 -0
  190. package/src/platform/vscode/index.ts +5 -0
  191. package/src/service/database.ts +2 -6
  192. package/vite.config.ts +46 -6
  193. package/vite.config.vscode.ts +47 -0
@@ -0,0 +1,341 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { ConnectionEntity } from './model/connection.entity';
5
+ import { DataSource, type DataSourceOptions } from 'typeorm';
6
+
7
+ /**
8
+ * 数据库连接管理服务
9
+ * 负责管理数据库连接配置和连接实例
10
+ */
11
+ export class ConnectionService {
12
+
13
+ /**
14
+ * 连接配置文件路径
15
+ * 优先使用环境变量 DB_TOOL_DATA_DIR,否则使用用户主目录下的 .db-tool 目录
16
+ */
17
+ private readonly configPath: string;
18
+
19
+ /**
20
+ * 活跃的数据库连接实例
21
+ */
22
+ private activeConnections: Map<string, DataSource> = new Map();
23
+
24
+ constructor() {
25
+ const dataDir = process.env.DB_TOOL_DATA_DIR || path.join(os.homedir(), '.fdb2');
26
+ this.configPath = path.join(dataDir, 'connections.json');
27
+ }
28
+
29
+ /**
30
+ * 初始化服务,创建配置目录
31
+ */
32
+ async init() {
33
+ const configDir = path.dirname(this.configPath);
34
+ if (!fs.existsSync(configDir)) {
35
+ fs.mkdirSync(configDir, { recursive: true });
36
+ }
37
+ }
38
+
39
+ /**
40
+ * 获取所有数据库连接配置
41
+ */
42
+ async getAllConnections(): Promise<ConnectionEntity[]> {
43
+ try {
44
+ if (!fs.existsSync(this.configPath)) {
45
+ return [];
46
+ }
47
+ const data = fs.readFileSync(this.configPath, 'utf8');
48
+ return JSON.parse(data) as ConnectionEntity[];
49
+ } catch (error) {
50
+ console.error('读取连接配置失败:', error);
51
+ return [];
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 根据ID获取数据库连接配置
57
+ */
58
+ async getConnectionById(id: string): Promise<ConnectionEntity | null> {
59
+ const connections = await this.getAllConnections();
60
+ return connections.find(conn => conn.id === id) || null;
61
+ }
62
+
63
+ /**
64
+ * 添加数据库连接配置
65
+ */
66
+ async addConnection(connection: ConnectionEntity): Promise<ConnectionEntity> {
67
+ const connections = await this.getAllConnections();
68
+
69
+ // 检查名称是否重复
70
+ if (connections.find(conn => conn.name === connection.name)) {
71
+ throw new Error('连接名称已存在');
72
+ }
73
+
74
+ // 生成ID并设置时间戳
75
+ connection.id = this.generateId();
76
+ connection.createdAt = new Date();
77
+ connection.updatedAt = new Date();
78
+ connection.enabled = connection.enabled !== undefined ? connection.enabled : true;
79
+
80
+ connections.push(connection);
81
+ await this.saveConnections(connections);
82
+
83
+ return connection;
84
+ }
85
+
86
+ /**
87
+ * 更新数据库连接配置
88
+ */
89
+ async updateConnection(id: string, updates: Partial<ConnectionEntity>): Promise<ConnectionEntity> {
90
+ const connections = await this.getAllConnections();
91
+ const index = connections.findIndex(conn => conn.id === id);
92
+
93
+ if (index === -1) {
94
+ throw new Error('连接配置不存在');
95
+ }
96
+
97
+ // 检查名称重复
98
+ if (updates.name && connections.find((conn, idx) => conn.name === updates.name && idx !== index)) {
99
+ throw new Error('连接名称已存在');
100
+ }
101
+ // @ts-ignore
102
+ connections[index] = { ...connections[index], ...updates, updatedAt: new Date() };
103
+ await this.saveConnections(connections);
104
+ // @ts-ignore
105
+ return connections[index];
106
+ }
107
+
108
+ /**
109
+ * 删除数据库连接配置
110
+ */
111
+ async deleteConnection(id: string): Promise<void> {
112
+ const connections = await this.getAllConnections();
113
+ const filteredConnections = connections.filter(conn => conn.id !== id);
114
+
115
+ if (filteredConnections.length === connections.length) {
116
+ throw new Error('连接配置不存在');
117
+ }
118
+
119
+ // 关闭活跃连接
120
+ if (this.activeConnections.has(id)) {
121
+ await this.activeConnections.get(id)?.destroy();
122
+ this.activeConnections.delete(id);
123
+ }
124
+
125
+ await this.saveConnections(filteredConnections);
126
+ }
127
+
128
+ /**
129
+ * 测试数据库连接
130
+ */
131
+ async testConnection(connection: ConnectionEntity): Promise<boolean> {
132
+ try {
133
+ console.log('test', connection);
134
+ const tempDataSource = await this.createTypeORMDataSource(connection);
135
+ await tempDataSource.query('SELECT 1');
136
+ await tempDataSource.destroy();
137
+ return true;
138
+ } catch (error) {
139
+ console.error(error);
140
+ return false;
141
+ }
142
+ }
143
+
144
+ /**
145
+ * 获取活跃的数据库连接
146
+ */
147
+ async getActiveConnection(id: string, database?: string): Promise<DataSource> {
148
+ const key = database ? `${id}_${database}` : id;
149
+ if (this.activeConnections.has(key)) {
150
+ const db = this.activeConnections.get(key);
151
+ // 检查连接是否仍然有效
152
+ if (db?.isInitialized) {
153
+ return db;
154
+ } else {
155
+ // 连接已关闭,从缓存中移除
156
+ this.activeConnections.delete(key);
157
+ }
158
+ }
159
+
160
+ // 连接池大小限制,防止连接数无限增长
161
+ if (this.activeConnections.size >= 10) {
162
+ // 关闭最旧的连接
163
+ const oldestKey = this.activeConnections.keys().next().value || '';
164
+ const oldestConnection = this.activeConnections.get(oldestKey);
165
+ try {
166
+ await oldestConnection?.destroy();
167
+ } catch (error) {
168
+ console.error(`关闭旧连接 ${oldestKey} 失败:`, error);
169
+ }
170
+ this.activeConnections.delete(oldestKey);
171
+ }
172
+
173
+ const connectionConfig = await this.getConnectionById(id);
174
+ if (!connectionConfig) {
175
+ throw new Error('连接配置不存在');
176
+ }
177
+
178
+ // 创建一个新的连接配置,使用指定的数据库
179
+ const updatedConnectionConfig: ConnectionEntity = {
180
+ ...connectionConfig,
181
+ database: database || connectionConfig.database
182
+ };
183
+
184
+ const dataSource = await this.createTypeORMDataSource(updatedConnectionConfig);
185
+ this.activeConnections.set(key, dataSource);
186
+
187
+ return dataSource;
188
+ }
189
+
190
+ /**
191
+ * 关闭数据库连接
192
+ */
193
+ async closeConnection(id: string, database?: string): Promise<void> {
194
+ const key = database ? `${id}_${database}` : id;
195
+ if (this.activeConnections.has(key)) {
196
+ await this.activeConnections.get(key)?.destroy();
197
+ this.activeConnections.delete(key);
198
+ }
199
+ // 也关闭默认连接(如果存在)
200
+ if (database && this.activeConnections.has(id)) {
201
+ await this.activeConnections.get(id)?.destroy();
202
+ this.activeConnections.delete(id);
203
+ }
204
+ }
205
+
206
+ /**
207
+ * 关闭特定连接的所有数据库连接
208
+ */
209
+ async closeAllConnectionsForId(connectionId: string): Promise<void> {
210
+ const keysToDelete: string[] = [];
211
+ for (const [key, dataSource] of this.activeConnections) {
212
+ if (key.startsWith(connectionId + '_') || key === connectionId) {
213
+ try {
214
+ await dataSource.destroy();
215
+ keysToDelete.push(key);
216
+ } catch (error) {
217
+ console.error(`关闭连接 ${key} 失败:`, error);
218
+ }
219
+ }
220
+ }
221
+ keysToDelete.forEach(key => this.activeConnections.delete(key));
222
+ }
223
+
224
+ /**
225
+ * 关闭所有数据库连接
226
+ */
227
+ async closeAllConnections(): Promise<void> {
228
+ for (const [id, dataSource] of this.activeConnections) {
229
+ try {
230
+ await dataSource.destroy();
231
+ } catch (error) {
232
+ console.error(`关闭连接 ${id} 失败:`, error);
233
+ }
234
+ }
235
+ this.activeConnections.clear();
236
+ }
237
+
238
+ /**
239
+ * 创建TypeORM数据源
240
+ */
241
+ private async createTypeORMDataSource(connectionConfig: ConnectionEntity): Promise<DataSource> {
242
+ const connectionOptions = this.getTypeORMOptions(connectionConfig);
243
+ return new DataSource(connectionOptions).initialize();
244
+ }
245
+
246
+ /**
247
+ * 获取TypeORM连接配置
248
+ */
249
+ private getTypeORMOptions(connectionConfig: ConnectionEntity): DataSourceOptions {
250
+ const baseOptions = {
251
+ type: connectionConfig.type as any,
252
+ host: connectionConfig.host,
253
+ port: connectionConfig.port,
254
+ username: connectionConfig.username,
255
+ password: connectionConfig.password,
256
+ database: connectionConfig.database,
257
+ synchronize: false,
258
+ logging: false,
259
+ // 关键配置:开启多语句执行
260
+ extra: {
261
+ multipleStatements: true
262
+ },
263
+ ...connectionConfig.options
264
+ };
265
+
266
+ // 根据数据库类型调整配置
267
+ switch (connectionConfig.type.toLowerCase()) {
268
+ case 'sqlite':
269
+ return {
270
+ ...baseOptions,
271
+ type: 'sqlite' as any,
272
+ database: connectionConfig.database,
273
+ host: undefined,
274
+ port: undefined,
275
+ username: undefined,
276
+ password: undefined
277
+ };
278
+ case 'postgres':
279
+ case 'postgresql':
280
+ return {
281
+ ...baseOptions,
282
+ type: 'postgres' as any,
283
+ ssl: connectionConfig.options?.ssl || false
284
+ };
285
+ case 'oracle':
286
+ return {
287
+ ...baseOptions,
288
+ type: 'oracle' as any,
289
+ connectString: `${connectionConfig.host}:${connectionConfig.port}/${connectionConfig.database}`,
290
+ host: undefined,
291
+ port: undefined,
292
+ database: undefined,
293
+ extra: {
294
+ connectionTimeout: 60000,
295
+ poolMax: 10,
296
+ poolMin: 1,
297
+ poolIncrement: 1
298
+ }
299
+ };
300
+ case 'mssql':
301
+ case 'sqlserver':
302
+ return {
303
+ ...baseOptions,
304
+ type: 'mssql' as any,
305
+ options: {
306
+ encrypt: connectionConfig.options?.encrypt || false,
307
+ trustServerCertificate: true
308
+ },
309
+ extra: {
310
+ connectionTimeout: 60000,
311
+ requestTimeout: 15000
312
+ }
313
+ };
314
+ default:
315
+ return baseOptions;
316
+ }
317
+ }
318
+
319
+ /**
320
+ * 保存连接配置到文件
321
+ */
322
+ private async saveConnections(connections: ConnectionEntity[]): Promise<void> {
323
+ try {
324
+ const dir = path.dirname(this.configPath);
325
+ if (!fs.existsSync(dir)) {
326
+ fs.mkdirSync(dir, { recursive: true });
327
+ }
328
+ fs.writeFileSync(this.configPath, JSON.stringify(connections, null, 2), 'utf8');
329
+ } catch (error) {
330
+ console.error('保存连接配置失败:', error);
331
+ throw error;
332
+ }
333
+ }
334
+
335
+ /**
336
+ * 生成唯一ID
337
+ */
338
+ private generateId(): string {
339
+ return Date.now().toString(36) + Math.random().toString(36).substr(2);
340
+ }
341
+ }