aicodeswitch 3.9.4 → 4.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.
@@ -1,353 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
36
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
37
- return new (P || (P = Promise))(function (resolve, reject) {
38
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
40
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
41
- step((generator = generator.apply(thisArg, _arguments || [])).next());
42
- });
43
- };
44
- var __rest = (this && this.__rest) || function (s, e) {
45
- var t = {};
46
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
47
- t[p] = s[p];
48
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
49
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
50
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
51
- t[p[i]] = s[p[i]];
52
- }
53
- return t;
54
- };
55
- var __importDefault = (this && this.__importDefault) || function (mod) {
56
- return (mod && mod.__esModule) ? mod : { "default": mod };
57
- };
58
- Object.defineProperty(exports, "__esModule", { value: true });
59
- exports.migrateToFileSystem = migrateToFileSystem;
60
- exports.migrateLegacyFsData = migrateLegacyFsData;
61
- exports.needsMigration = needsMigration;
62
- exports.verifyMigration = verifyMigration;
63
- const path_1 = __importDefault(require("path"));
64
- const promises_1 = __importDefault(require("fs/promises"));
65
- /**
66
- * 数据库迁移工具
67
- * 从 better-sqlite3 和 leveldb 迁移到文件系统数据库
68
- */
69
- function migrateToFileSystem(sourceDataPath_1) {
70
- return __awaiter(this, arguments, void 0, function* (sourceDataPath, targetDataPath = sourceDataPath) {
71
- console.log('[Migration] Starting migration to file system database...');
72
- try {
73
- // 动态导入旧数据库(如果存在)
74
- const oldDbPath = path_1.default.join(sourceDataPath, 'app.db');
75
- const oldDbExists = yield promises_1.default.access(oldDbPath).then(() => true).catch(() => false);
76
- if (!oldDbExists) {
77
- console.log('[Migration] No old database found, skipping migration');
78
- return;
79
- }
80
- yield promises_1.default.mkdir(targetDataPath, { recursive: true });
81
- // 尝试导入旧数据库模块(仅在有 SQLite 依赖时可用)
82
- let DatabaseManager;
83
- try {
84
- const dbModule = yield Promise.resolve().then(() => __importStar(require('./database.js')));
85
- DatabaseManager = dbModule.DatabaseManager;
86
- }
87
- catch (error) {
88
- console.log('[Migration] Old database module not available');
89
- console.log('[Migration] This is expected if better-sqlite3 is not installed');
90
- console.log('[Migration] To migrate old data, please run: yarn add better-sqlite3 level');
91
- console.log('[Migration] Then run the migration again');
92
- return;
93
- }
94
- // 创建旧数据库实例
95
- console.log('[Migration] Initializing old database...');
96
- const oldDb = new DatabaseManager(sourceDataPath);
97
- yield oldDb.initialize();
98
- // 导出核心数据
99
- console.log('[Migration] Exporting core data from old database...');
100
- const vendors = oldDb.getVendors();
101
- const services = oldDb.getAPIServices();
102
- const routes = oldDb.getRoutes();
103
- const rules = oldDb.getRules();
104
- const config = oldDb.getConfig();
105
- console.log(`[Migration] Found ${vendors.length} vendors`);
106
- console.log(`[Migration] Found ${services.length} services`);
107
- console.log(`[Migration] Found ${routes.length} routes`);
108
- console.log(`[Migration] Found ${rules.length} rules`);
109
- // 将 services 按 vendorId 分组并嵌入到 vendors 中
110
- console.log('[Migration] Restructuring vendors with nested services...');
111
- const servicesByVendor = new Map();
112
- for (const service of services) {
113
- if (!service.vendorId) {
114
- console.warn(`[Migration] Skipping service without vendorId: ${service.id}`);
115
- continue;
116
- }
117
- if (!servicesByVendor.has(service.vendorId)) {
118
- servicesByVendor.set(service.vendorId, []);
119
- }
120
- // 移除 vendorId 字段,因为现在通过父级关系隐式关联
121
- const { vendorId } = service, serviceWithoutVendorId = __rest(service, ["vendorId"]);
122
- servicesByVendor.get(service.vendorId).push(serviceWithoutVendorId);
123
- }
124
- // 为每个 vendor 添加 services 数组
125
- const vendorsWithServices = vendors.map((vendor) => (Object.assign(Object.assign({}, vendor), { services: servicesByVendor.get(vendor.id) || [] })));
126
- console.log('[Migration] Restructuring completed');
127
- // 保存核心数据到新的文件系统格式
128
- console.log('[Migration] Saving core data to file system...');
129
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'vendors.json'), JSON.stringify(vendorsWithServices, null, 2));
130
- // 不再保存独立的 services.json,已合并到 vendors.json 中
131
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'routes.json'), JSON.stringify({ routes, rules }, null, 2));
132
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'config.json'), JSON.stringify(config, null, 2));
133
- // 迁移 sessions(如果存在)
134
- try {
135
- console.log('[Migration] Migrating sessions...');
136
- const sessions = oldDb.getSessions(10000, 0);
137
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'sessions.json'), JSON.stringify(sessions, null, 2));
138
- console.log(`[Migration] Migrated ${sessions.length} sessions`);
139
- }
140
- catch (error) {
141
- console.log('[Migration] Could not migrate sessions:', error);
142
- // 创建空的 sessions 文件
143
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'sessions.json'), JSON.stringify([], null, 2));
144
- }
145
- // 迁移请求日志(限制数量以避免文件过大)
146
- try {
147
- console.log('[Migration] Migrating request logs (last 5000)...');
148
- const logs = yield oldDb.getLogs(5000, 0);
149
- // 完整迁移所有日志,不进行任何截断
150
- if (logs.length > 0) {
151
- // 修复字段名:将 response 改为 responseBody
152
- const cleanedLogs = logs.map((log) => (Object.assign(Object.assign({}, log), {
153
- // 兼容旧的 response 字段名,重命名为 responseBody
154
- responseBody: log.responseBody || log.response,
155
- // 移除旧的 response 字段(如果存在)
156
- response: undefined })));
157
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'logs.json'), JSON.stringify(cleanedLogs, null, 2));
158
- console.log(`[Migration] Migrated ${logs.length} request logs`);
159
- }
160
- else {
161
- // 创建空的日志文件
162
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'logs.json'), JSON.stringify([], null, 2));
163
- console.log('[Migration] No request logs to migrate');
164
- }
165
- }
166
- catch (error) {
167
- console.log('[Migration] Could not migrate logs:', error instanceof Error ? error.message : error);
168
- // 创建空的日志文件
169
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'logs.json'), JSON.stringify([], null, 2));
170
- }
171
- // 迁移错误日志
172
- try {
173
- console.log('[Migration] Migrating error logs (last 1000)...');
174
- const errorLogs = yield oldDb.getErrorLogs(1000, 0);
175
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'error-logs.json'), JSON.stringify(errorLogs, null, 2));
176
- console.log(`[Migration] Migrated ${errorLogs.length} error logs`);
177
- }
178
- catch (error) {
179
- console.log('[Migration] Could not migrate error logs:', error);
180
- // 创建空的错误日志文件
181
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'error-logs.json'), JSON.stringify([], null, 2));
182
- }
183
- // 创建空的黑名单文件
184
- yield promises_1.default.writeFile(path_1.default.join(targetDataPath, 'blacklist.json'), JSON.stringify([], null, 2));
185
- // 关闭旧数据库连接
186
- try {
187
- console.log('[Migration] Closing old database connections...');
188
- oldDb.close();
189
- // 等待一下确保文件句柄被释放
190
- yield new Promise(resolve => setTimeout(resolve, 1000));
191
- console.log('[Migration] Old database connections closed');
192
- }
193
- catch (error) {
194
- console.log('[Migration] Warning: Could not close old database:', error instanceof Error ? error.message : error);
195
- }
196
- // 保留原始数据库文件,不进行备份或重命名
197
- // 这样如果迁移失败,用户可以使用老版本继续运行
198
- console.log('[Migration] ✅ Migration data export completed successfully!');
199
- console.log('[Migration] Original database files preserved for rollback');
200
- }
201
- catch (error) {
202
- console.error('[Migration] ❌ Migration failed:', error);
203
- console.error('[Migration] Stack trace:', error.stack);
204
- throw error;
205
- }
206
- });
207
- }
208
- /**
209
- * 迁移旧版本的文件系统数据库目录到新目录(仅复制 JSON/日志文件)
210
- */
211
- function migrateLegacyFsData(legacyDataPath, targetDataPath) {
212
- return __awaiter(this, void 0, void 0, function* () {
213
- console.log('[Migration] Migrating legacy filesystem data directory...');
214
- yield promises_1.default.mkdir(targetDataPath, { recursive: true });
215
- const filesToCopy = [
216
- 'vendors.json',
217
- 'services.json',
218
- 'routes.json',
219
- 'rules.json',
220
- 'config.json',
221
- 'sessions.json',
222
- 'logs.json',
223
- 'logs-index.json',
224
- 'error-logs.json',
225
- 'blacklist.json',
226
- 'statistics.json',
227
- ];
228
- for (const filename of filesToCopy) {
229
- const src = path_1.default.join(legacyDataPath, filename);
230
- const dest = path_1.default.join(targetDataPath, filename);
231
- const exists = yield promises_1.default.access(src).then(() => true).catch(() => false);
232
- if (exists) {
233
- yield promises_1.default.copyFile(src, dest);
234
- }
235
- }
236
- const legacyLogsDir = path_1.default.join(legacyDataPath, 'logs');
237
- const targetLogsDir = path_1.default.join(targetDataPath, 'logs');
238
- const logsDirExists = yield promises_1.default.access(legacyLogsDir).then(() => true).catch(() => false);
239
- if (logsDirExists) {
240
- yield promises_1.default.cp(legacyLogsDir, targetLogsDir, { recursive: true });
241
- }
242
- console.log('[Migration] Legacy filesystem data migration completed');
243
- });
244
- }
245
- /**
246
- * 检查是否需要迁移
247
- * @param dataPath 数据目录路径
248
- * @returns 是否需要迁移
249
- */
250
- function needsMigration(sourceDataPath_1) {
251
- return __awaiter(this, arguments, void 0, function* (sourceDataPath, targetDataPath = sourceDataPath) {
252
- try {
253
- // 检查是否存在旧的 SQLite 数据库
254
- const oldDbPath = path_1.default.join(sourceDataPath, 'app.db');
255
- const oldDbExists = yield promises_1.default.access(oldDbPath).then(() => true).catch(() => false);
256
- if (!oldDbExists) {
257
- return false;
258
- }
259
- // 检查是否已经存在新的文件系统数据库
260
- const newDbPath = path_1.default.join(targetDataPath, 'config.json');
261
- const newDbExists = yield promises_1.default.access(newDbPath).then(() => true).catch(() => false);
262
- // 如果旧数据库存在且新数据库不存在,则需要迁移
263
- return oldDbExists && !newDbExists;
264
- }
265
- catch (error) {
266
- console.error('[Migration] Error checking migration status:', error);
267
- return false;
268
- }
269
- });
270
- }
271
- /**
272
- * 验证迁移结果
273
- * @param dataPath 数据目录路径
274
- * @returns 验证结果
275
- */
276
- function verifyMigration(dataPath) {
277
- return __awaiter(this, void 0, void 0, function* () {
278
- const errors = [];
279
- const warnings = [];
280
- try {
281
- // 检查必需的文件(移除了 services.json,因为现在合并到 vendors.json 中)
282
- const requiredFiles = [
283
- 'vendors.json',
284
- 'routes.json',
285
- 'config.json',
286
- 'sessions.json',
287
- 'logs.json',
288
- 'error-logs.json',
289
- 'blacklist.json',
290
- ];
291
- for (const file of requiredFiles) {
292
- const filePath = path_1.default.join(dataPath, file);
293
- try {
294
- yield promises_1.default.access(filePath);
295
- // 尝试解析 JSON
296
- const content = yield promises_1.default.readFile(filePath, 'utf-8');
297
- JSON.parse(content);
298
- // 特殊验证:确保 vendors.json 包含 services 数组
299
- if (file === 'vendors.json') {
300
- const vendors = JSON.parse(content);
301
- for (const vendor of vendors) {
302
- if (!Array.isArray(vendor.services)) {
303
- errors.push(`Invalid vendors.json: vendor ${vendor.id} is missing services array`);
304
- }
305
- }
306
- }
307
- // 特殊验证:确保 routes.json 包含 routes 与 rules
308
- if (file === 'routes.json') {
309
- const routesData = JSON.parse(content);
310
- if (!routesData || typeof routesData !== 'object') {
311
- errors.push('Invalid routes.json: missing routes/rules object');
312
- }
313
- else {
314
- if (!Array.isArray(routesData.routes)) {
315
- errors.push('Invalid routes.json: routes is not an array');
316
- }
317
- if (!Array.isArray(routesData.rules)) {
318
- errors.push('Invalid routes.json: rules is not an array');
319
- }
320
- }
321
- }
322
- }
323
- catch (error) {
324
- errors.push(`File ${file} is missing or invalid`);
325
- }
326
- }
327
- // 可选文件检查(services.json)
328
- const oldServicesFile = path_1.default.join(dataPath, 'services.json');
329
- const oldServicesExists = yield promises_1.default.access(oldServicesFile).then(() => true).catch(() => false);
330
- if (oldServicesExists) {
331
- warnings.push('Old services.json file still exists (should have been migrated to vendors.json)');
332
- }
333
- const oldRulesFile = path_1.default.join(dataPath, 'rules.json');
334
- const oldRulesExists = yield promises_1.default.access(oldRulesFile).then(() => true).catch(() => false);
335
- if (oldRulesExists) {
336
- warnings.push('Old rules.json file still exists (should have been migrated to routes.json)');
337
- }
338
- return {
339
- success: errors.length === 0,
340
- errors,
341
- warnings,
342
- };
343
- }
344
- catch (error) {
345
- errors.push(`Verification failed: ${error.message}`);
346
- return {
347
- success: false,
348
- errors,
349
- warnings,
350
- };
351
- }
352
- });
353
- }