@tencent-connect/openclaw-qqbot 1.6.4-alpha.13 → 1.6.4-alpha.14
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.
- package/dist/src/slash-commands.js +37 -8
- package/package.json +1 -1
- package/src/slash-commands.ts +35 -8
|
@@ -337,26 +337,55 @@ function switchPluginSourceToNpm() {
|
|
|
337
337
|
const cfgPath = path.join(homeDir, `.${cli}`, `${cli}.json`);
|
|
338
338
|
if (!fs.existsSync(cfgPath))
|
|
339
339
|
continue;
|
|
340
|
-
//
|
|
340
|
+
// 读取当前配置(保留原始文本用于回退)
|
|
341
341
|
const raw = fs.readFileSync(cfgPath, "utf8");
|
|
342
|
-
|
|
342
|
+
let cfg;
|
|
343
|
+
try {
|
|
344
|
+
cfg = JSON.parse(raw);
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// 配置文件已经是损坏的 JSON,不要继续操作以免加剧问题
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
343
350
|
const inst = cfg?.plugins?.installs?.["openclaw-qqbot"];
|
|
344
351
|
if (!inst || inst.source === "npm") {
|
|
345
352
|
break; // 无需修改
|
|
346
353
|
}
|
|
347
|
-
//
|
|
348
|
-
const channelsBefore = JSON.stringify(cfg.channels
|
|
354
|
+
// 记录修改前的完整快照,用于写后校验
|
|
355
|
+
const channelsBefore = JSON.stringify(cfg.channels ?? null);
|
|
349
356
|
inst.source = "npm";
|
|
350
357
|
delete inst.sourcePath;
|
|
351
358
|
const newRaw = JSON.stringify(cfg, null, 4) + "\n";
|
|
352
|
-
//
|
|
353
|
-
|
|
354
|
-
|
|
359
|
+
// 写后校验:重新解析确认整个 JSON 合法且 channels 未被破坏
|
|
360
|
+
let verify;
|
|
361
|
+
try {
|
|
362
|
+
verify = JSON.parse(newRaw);
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// stringify 后竟然无法 parse(理论上不会),放弃写入
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
const channelsAfter = JSON.stringify(verify.channels ?? null);
|
|
355
369
|
if (channelsBefore !== channelsAfter) {
|
|
356
370
|
// channels 数据异常,放弃写入
|
|
357
371
|
break;
|
|
358
372
|
}
|
|
359
|
-
|
|
373
|
+
// 原子写入:先写临时文件,再 rename 替换,避免写入中途崩溃导致配置文件损坏
|
|
374
|
+
const tmpPath = cfgPath + ".qqbot-upgrade.tmp";
|
|
375
|
+
fs.writeFileSync(tmpPath, newRaw, { mode: 0o644 });
|
|
376
|
+
// 再次校验临时文件的完整性
|
|
377
|
+
try {
|
|
378
|
+
JSON.parse(fs.readFileSync(tmpPath, "utf8"));
|
|
379
|
+
}
|
|
380
|
+
catch {
|
|
381
|
+
// 写入的临时文件不完整,清理后放弃
|
|
382
|
+
try {
|
|
383
|
+
fs.unlinkSync(tmpPath);
|
|
384
|
+
}
|
|
385
|
+
catch { }
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
fs.renameSync(tmpPath, cfgPath);
|
|
360
389
|
break;
|
|
361
390
|
}
|
|
362
391
|
}
|
package/package.json
CHANGED
package/src/slash-commands.ts
CHANGED
|
@@ -433,30 +433,57 @@ function switchPluginSourceToNpm(): void {
|
|
|
433
433
|
const cfgPath = path.join(homeDir, `.${cli}`, `${cli}.json`);
|
|
434
434
|
if (!fs.existsSync(cfgPath)) continue;
|
|
435
435
|
|
|
436
|
-
//
|
|
436
|
+
// 读取当前配置(保留原始文本用于回退)
|
|
437
437
|
const raw = fs.readFileSync(cfgPath, "utf8");
|
|
438
|
-
|
|
438
|
+
|
|
439
|
+
let cfg: any;
|
|
440
|
+
try {
|
|
441
|
+
cfg = JSON.parse(raw);
|
|
442
|
+
} catch {
|
|
443
|
+
// 配置文件已经是损坏的 JSON,不要继续操作以免加剧问题
|
|
444
|
+
break;
|
|
445
|
+
}
|
|
446
|
+
|
|
439
447
|
const inst = cfg?.plugins?.installs?.["openclaw-qqbot"];
|
|
440
448
|
if (!inst || inst.source === "npm") {
|
|
441
449
|
break; // 无需修改
|
|
442
450
|
}
|
|
443
451
|
|
|
444
|
-
//
|
|
445
|
-
const channelsBefore = JSON.stringify(cfg.channels
|
|
452
|
+
// 记录修改前的完整快照,用于写后校验
|
|
453
|
+
const channelsBefore = JSON.stringify(cfg.channels ?? null);
|
|
446
454
|
|
|
447
455
|
inst.source = "npm";
|
|
448
456
|
delete inst.sourcePath;
|
|
449
457
|
const newRaw = JSON.stringify(cfg, null, 4) + "\n";
|
|
450
458
|
|
|
451
|
-
//
|
|
452
|
-
|
|
453
|
-
|
|
459
|
+
// 写后校验:重新解析确认整个 JSON 合法且 channels 未被破坏
|
|
460
|
+
let verify: any;
|
|
461
|
+
try {
|
|
462
|
+
verify = JSON.parse(newRaw);
|
|
463
|
+
} catch {
|
|
464
|
+
// stringify 后竟然无法 parse(理论上不会),放弃写入
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
const channelsAfter = JSON.stringify(verify.channels ?? null);
|
|
454
468
|
if (channelsBefore !== channelsAfter) {
|
|
455
469
|
// channels 数据异常,放弃写入
|
|
456
470
|
break;
|
|
457
471
|
}
|
|
458
472
|
|
|
459
|
-
|
|
473
|
+
// 原子写入:先写临时文件,再 rename 替换,避免写入中途崩溃导致配置文件损坏
|
|
474
|
+
const tmpPath = cfgPath + ".qqbot-upgrade.tmp";
|
|
475
|
+
fs.writeFileSync(tmpPath, newRaw, { mode: 0o644 });
|
|
476
|
+
|
|
477
|
+
// 再次校验临时文件的完整性
|
|
478
|
+
try {
|
|
479
|
+
JSON.parse(fs.readFileSync(tmpPath, "utf8"));
|
|
480
|
+
} catch {
|
|
481
|
+
// 写入的临时文件不完整,清理后放弃
|
|
482
|
+
try { fs.unlinkSync(tmpPath); } catch {}
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
fs.renameSync(tmpPath, cfgPath);
|
|
460
487
|
break;
|
|
461
488
|
}
|
|
462
489
|
} catch {
|