karin-plugin-kkk 2.45.0-beta.3 → 2.45.0-beta.5
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/CHANGELOG.md +15 -0
- package/lib/build-metadata.json +5 -5
- package/lib/core_chunk/main.js +103 -34
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [2.45.0-beta.5](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.45.0-beta.4...v2.45.0-beta.5) (2026-10-06)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🐛 错误修复
|
|
9
|
+
|
|
10
|
+
* 更新 node-karin 依赖版本至 1.18.0 ([42ef2e2](https://github.com/ikenxuan/karin-plugin-kkk/commit/42ef2e2729556b7a4c75c68f7ee1714b6581ced2))
|
|
11
|
+
|
|
12
|
+
## [2.45.0-beta.4](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.45.0-beta.3...v2.45.0-beta.4) (2026-10-06)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### 🐛 错误修复
|
|
16
|
+
|
|
17
|
+
* 优化更新检测逻辑,支持逐渠道版本锁定与提醒 ([ddfd011](https://github.com/ikenxuan/karin-plugin-kkk/commit/ddfd011ac3bcd49789870a2e154003973c52cea9))
|
|
18
|
+
* 优化更新逻辑以支持金丝雀用户的版本解锁和范围起点解析 ([4a28ce5](https://github.com/ikenxuan/karin-plugin-kkk/commit/4a28ce55b82115683713ad6985d456751f151c23))
|
|
19
|
+
|
|
5
20
|
## [2.45.0-beta.3](https://github.com/ikenxuan/karin-plugin-kkk/compare/v2.45.0-beta.2...v2.45.0-beta.3) (2026-10-06)
|
|
6
21
|
|
|
7
22
|
|
package/lib/build-metadata.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.45.0-beta.
|
|
3
|
-
"buildTime": "2026-10-
|
|
4
|
-
"buildTimestamp":
|
|
2
|
+
"version": "2.45.0-beta.5",
|
|
3
|
+
"buildTime": "2026-10-06T08:25:30.584Z",
|
|
4
|
+
"buildTimestamp": 1791275130584,
|
|
5
5
|
"name": "karin-plugin-kkk",
|
|
6
6
|
"description": "Karin 的「抖音」「B 站」视频解析/动态推送插件",
|
|
7
7
|
"homepage": "https://github.com/ikenxuan/karin-plugin-kkk",
|
|
8
|
-
"commitHash": "
|
|
9
|
-
"shortCommitHash": "
|
|
8
|
+
"commitHash": "29a1c8b38919021e5788a3ab88067b20104e9d96",
|
|
9
|
+
"shortCommitHash": "29a1c8b3"
|
|
10
10
|
}
|
package/lib/core_chunk/main.js
CHANGED
|
@@ -7841,8 +7841,17 @@ var Render = async (event, path, data) => {
|
|
|
7841
7841
|
const templateType = path.split("/")[0];
|
|
7842
7842
|
let hasUpdate = false;
|
|
7843
7843
|
try {
|
|
7844
|
-
const
|
|
7845
|
-
|
|
7844
|
+
for (const channel of [
|
|
7845
|
+
"stable",
|
|
7846
|
+
"beta",
|
|
7847
|
+
"rc"
|
|
7848
|
+
]) {
|
|
7849
|
+
const lockedVersion = await db.get(`kkk:update:lock:${channel}`);
|
|
7850
|
+
if (typeof lockedVersion === "string" && lockedVersion.length > 0 && isSemverGreater(lockedVersion, Root.pluginVersion)) {
|
|
7851
|
+
hasUpdate = true;
|
|
7852
|
+
break;
|
|
7853
|
+
}
|
|
7854
|
+
}
|
|
7846
7855
|
} catch {}
|
|
7847
7856
|
const useDarkTheme = await resolveUseDarkTheme(path, data);
|
|
7848
7857
|
const result = await renderTemplate(path, data, {
|
|
@@ -24561,6 +24570,15 @@ var updateHelp_default = defineTemplate({
|
|
|
24561
24570
|
active: true
|
|
24562
24571
|
};
|
|
24563
24572
|
const order = semverCompare(channel.version ?? "0.0.0", data.currentVersion);
|
|
24573
|
+
if (channel.hasUpdate !== void 0) return channel.hasUpdate ? {
|
|
24574
|
+
dot: palette.success,
|
|
24575
|
+
text: "有更新可升级",
|
|
24576
|
+
active: true
|
|
24577
|
+
} : {
|
|
24578
|
+
dot: palette.faint,
|
|
24579
|
+
text: order < 0 ? "低于当前版本" : "已是最新",
|
|
24580
|
+
active: false
|
|
24581
|
+
};
|
|
24564
24582
|
if (order > 0) return {
|
|
24565
24583
|
dot: palette.success,
|
|
24566
24584
|
text: "有更新可升级",
|
|
@@ -40321,6 +40339,23 @@ var getLagVersionCount = (changelog, localVersion, remoteVersion) => {
|
|
|
40321
40339
|
}).length;
|
|
40322
40340
|
};
|
|
40323
40341
|
/**
|
|
40342
|
+
* 金丝雀用户的 range 起点解析:semver 的 ASCII 序(beta < canary)无法表达
|
|
40343
|
+
* 「发布晚于本机构建」——改按 pkg.pr.new 发布历史的时间线,取本机构建时间
|
|
40344
|
+
* 之前的最后一个发布版本作为 range 起点。失败返回 undefined(回退 semver)。
|
|
40345
|
+
*/
|
|
40346
|
+
var resolveCanaryRangeStart = async (buildTimestamp) => {
|
|
40347
|
+
if (!buildTimestamp) return void 0;
|
|
40348
|
+
try {
|
|
40349
|
+
const nodes = (await axios.get("https://pkg.pr.new/api/repo/commits?owner=ikenxuan&repo=karin-plugin-kkk", { timeout: 1e4 })).data?.target?.history?.nodes;
|
|
40350
|
+
if (!Array.isArray(nodes)) return void 0;
|
|
40351
|
+
for (const n of nodes) {
|
|
40352
|
+
const t = n.authoredDate ? new Date(n.authoredDate).getTime() : 0;
|
|
40353
|
+
const v = /v?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/.exec(n.message ?? "")?.[1];
|
|
40354
|
+
if (t > 0 && t <= buildTimestamp && v) return v;
|
|
40355
|
+
}
|
|
40356
|
+
} catch {}
|
|
40357
|
+
};
|
|
40358
|
+
/**
|
|
40324
40359
|
* 获取远程构建元数据
|
|
40325
40360
|
* @param version 远程版本号
|
|
40326
40361
|
* @returns 构建元数据对象,如果获取失败则返回 null
|
|
@@ -40393,9 +40428,10 @@ var getChangelogImage = async (ctx, props) => {
|
|
|
40393
40428
|
lagVersionCount = getLagVersionCount(changelog, props.localVersion, props.remoteVersion);
|
|
40394
40429
|
const remoteMeta = await getRemoteBuildMetadata(props.remoteVersion);
|
|
40395
40430
|
if (remoteMeta?.buildTime) buildTime = formatBuildTime(remoteMeta.buildTime);
|
|
40431
|
+
const rangeStart = parseReleaseChannel(props.localVersion) === "Canary" ? await resolveCanaryRangeStart(getBuildMetadata()?.buildTimestamp) ?? props.localVersion : props.localVersion;
|
|
40396
40432
|
changelog = range({
|
|
40397
40433
|
data: changelog,
|
|
40398
|
-
startVersion:
|
|
40434
|
+
startVersion: rangeStart,
|
|
40399
40435
|
endVersion: versionCore(props.remoteVersion),
|
|
40400
40436
|
compare: "semver"
|
|
40401
40437
|
});
|
|
@@ -40403,9 +40439,10 @@ var getChangelogImage = async (ctx, props) => {
|
|
|
40403
40439
|
try {
|
|
40404
40440
|
changelog = fs.readFileSync(Root.pluginPath + "/CHANGELOG.md", "utf8");
|
|
40405
40441
|
lagVersionCount = getLagVersionCount(changelog, props.localVersion, props.remoteVersion);
|
|
40442
|
+
const rangeStart = parseReleaseChannel(props.localVersion) === "Canary" ? await resolveCanaryRangeStart(getBuildMetadata()?.buildTimestamp) ?? props.localVersion : props.localVersion;
|
|
40406
40443
|
changelog = range({
|
|
40407
40444
|
data: changelog,
|
|
40408
|
-
startVersion:
|
|
40445
|
+
startVersion: rangeStart,
|
|
40409
40446
|
endVersion: versionCore(props.remoteVersion),
|
|
40410
40447
|
compare: "semver"
|
|
40411
40448
|
});
|
|
@@ -40428,45 +40465,64 @@ var getChangelogImage = async (ctx, props) => {
|
|
|
40428
40465
|
};
|
|
40429
40466
|
//#endregion
|
|
40430
40467
|
//#region src/apps/update.ts
|
|
40431
|
-
|
|
40468
|
+
/** 更新提醒的订阅渠道(与面板 UpdateNotifyChannels 可选项一致) */
|
|
40469
|
+
var UPDATE_CHANNELS = [
|
|
40470
|
+
"stable",
|
|
40471
|
+
"beta",
|
|
40472
|
+
"rc"
|
|
40473
|
+
];
|
|
40474
|
+
/** 各渠道更新提醒锁:记录该渠道上次已推送的版本,检测到新版本推送一次后上锁 */
|
|
40475
|
+
var updateLockKey = (channel) => `kkk:update:lock:${channel}`;
|
|
40432
40476
|
var UPDATE_MSGID_KEY = "kkk:update:msgid";
|
|
40477
|
+
/** 推送图对应的安装目标版本(引用回复推送图「更新」时安装它) */
|
|
40478
|
+
var UPDATE_PUSHED_KEY = "kkk:update:pushed";
|
|
40433
40479
|
/**
|
|
40434
40480
|
* 定时更新检测处理器
|
|
40435
|
-
*
|
|
40436
|
-
*
|
|
40481
|
+
* 逐渠道检查远程 dist-tag 版本:检测到该渠道有新版本就推送一次然后上锁,
|
|
40482
|
+
* 各渠道锁相互独立、互不挤占;金丝雀安装按构建时间线判定新版本。
|
|
40437
40483
|
*
|
|
40438
40484
|
* @returns 是否继续后续任务
|
|
40439
40485
|
*/
|
|
40440
40486
|
var Handler = async () => {
|
|
40441
|
-
const
|
|
40487
|
+
const channels = Config.app.UpdateNotifyChannels?.length ? Config.app.UpdateNotifyChannels : ["stable"];
|
|
40488
|
+
const tagOf = (c) => c === "stable" ? "latest" : c;
|
|
40442
40489
|
const installedIsCanary = parseReleaseChannel(Root.pluginVersion) === "Canary";
|
|
40443
40490
|
const installedBuildTime = getBuildMetadata()?.buildTimestamp;
|
|
40444
|
-
const
|
|
40491
|
+
const tagVersions = /* @__PURE__ */ new Map();
|
|
40492
|
+
await Promise.all([...new Set(channels.map(tagOf))].map(async (tag) => {
|
|
40445
40493
|
try {
|
|
40446
|
-
|
|
40494
|
+
if (!installedIsCanary) {
|
|
40495
|
+
const upd = await checkPkgUpdate(Root.pluginName, {
|
|
40496
|
+
tag,
|
|
40497
|
+
compare: "semver"
|
|
40498
|
+
});
|
|
40499
|
+
tagVersions.set(tag, upd.status === "yes" ? upd.remote : null);
|
|
40500
|
+
} else tagVersions.set(tag, await getRemotePkgVersion(Root.pluginName, tag) || null);
|
|
40447
40501
|
} catch {
|
|
40448
|
-
|
|
40502
|
+
tagVersions.set(tag, null);
|
|
40449
40503
|
}
|
|
40450
40504
|
}));
|
|
40451
40505
|
const canaryInfo = installedIsCanary ? await fetchCanaryInfo() : null;
|
|
40452
|
-
const
|
|
40506
|
+
const isNewVersion = (version) => {
|
|
40453
40507
|
if (installedIsCanary && installedBuildTime !== void 0) {
|
|
40454
40508
|
const releaseNode = canaryInfo?.nodes.find((n) => n.message.includes(version));
|
|
40455
40509
|
if (releaseNode) return releaseNode.time > installedBuildTime;
|
|
40456
40510
|
}
|
|
40457
40511
|
return isSemverGreater(version, Root.pluginVersion);
|
|
40458
|
-
}
|
|
40459
|
-
|
|
40460
|
-
|
|
40461
|
-
const
|
|
40462
|
-
if (
|
|
40463
|
-
|
|
40464
|
-
|
|
40465
|
-
|
|
40466
|
-
|
|
40467
|
-
|
|
40468
|
-
|
|
40469
|
-
}
|
|
40512
|
+
};
|
|
40513
|
+
const pending = /* @__PURE__ */ new Set();
|
|
40514
|
+
for (const channel of channels) {
|
|
40515
|
+
const version = tagVersions.get(tagOf(channel)) ?? null;
|
|
40516
|
+
if (!version || !isNewVersion(version)) continue;
|
|
40517
|
+
try {
|
|
40518
|
+
const locked = await db.get(updateLockKey(channel));
|
|
40519
|
+
if (typeof locked === "string" && locked === version) continue;
|
|
40520
|
+
await db.set(updateLockKey(channel), version);
|
|
40521
|
+
} catch {}
|
|
40522
|
+
pending.add(version);
|
|
40523
|
+
}
|
|
40524
|
+
if (pending.size === 0) return true;
|
|
40525
|
+
const installTarget = [...pending].sort((a, b) => isSemverGreater(b, a) ? 1 : -1)[0];
|
|
40470
40526
|
const masters = config.master().filter((id) => id !== "console");
|
|
40471
40527
|
if (masters.length === 0) return true;
|
|
40472
40528
|
const botItems = karin.getAllBotList().filter((b) => b.bot.account.name !== "console");
|
|
@@ -40486,12 +40542,16 @@ var Handler = async () => {
|
|
|
40486
40542
|
const botToImage = /* @__PURE__ */ new Map();
|
|
40487
40543
|
for (const item of botItems) {
|
|
40488
40544
|
if (!Array.from(masterToBot.entries()).some(([, b]) => b.account.selfId === item.bot.account.selfId)) continue;
|
|
40489
|
-
const
|
|
40490
|
-
|
|
40491
|
-
|
|
40492
|
-
|
|
40493
|
-
|
|
40494
|
-
|
|
40545
|
+
const elements = [segment.text("karin-plugin-kkk 有新的更新!")];
|
|
40546
|
+
for (const version of pending) {
|
|
40547
|
+
const img = await getChangelogImage({ bot: item.bot }, {
|
|
40548
|
+
localVersion: Root.pluginVersion,
|
|
40549
|
+
remoteVersion: version,
|
|
40550
|
+
Tip: true
|
|
40551
|
+
});
|
|
40552
|
+
if (img && img.length > 0) elements.push(...img);
|
|
40553
|
+
}
|
|
40554
|
+
if (elements.length > 1) botToImage.set(item.bot.account.selfId, elements);
|
|
40495
40555
|
}
|
|
40496
40556
|
let storedMsgId;
|
|
40497
40557
|
for (const owner of masters) {
|
|
@@ -40504,10 +40564,16 @@ var Handler = async () => {
|
|
|
40504
40564
|
}
|
|
40505
40565
|
if (storedMsgId) try {
|
|
40506
40566
|
await db.set(UPDATE_MSGID_KEY, storedMsgId);
|
|
40567
|
+
await db.set(UPDATE_PUSHED_KEY, installTarget);
|
|
40507
40568
|
} catch {}
|
|
40508
40569
|
return true;
|
|
40509
40570
|
};
|
|
40510
40571
|
var handleUpdateHook = wrapWithErrorHandler(async (e) => {
|
|
40572
|
+
const pushedVersion = await db.get(UPDATE_PUSHED_KEY);
|
|
40573
|
+
if (typeof pushedVersion === "string" && pushedVersion) {
|
|
40574
|
+
await installAndRestart(e, pushedVersion);
|
|
40575
|
+
return;
|
|
40576
|
+
}
|
|
40511
40577
|
e.reply("开始更新 karin-plugin-kkk ...", { reply: true });
|
|
40512
40578
|
const upd = await checkPkgUpdate(Root.pluginName, { compare: "semver" });
|
|
40513
40579
|
if (upd.status === "yes") {
|
|
@@ -40516,7 +40582,8 @@ var handleUpdateHook = wrapWithErrorHandler(async (e) => {
|
|
|
40516
40582
|
const msgResult = await e.reply(`${Root.pluginName} 更新成功!\n${result.local} -> ${result.remote}\n开始执行重启......`);
|
|
40517
40583
|
if (msgResult.messageId) try {
|
|
40518
40584
|
await db.del(UPDATE_MSGID_KEY);
|
|
40519
|
-
await db.del(
|
|
40585
|
+
await db.del(UPDATE_PUSHED_KEY);
|
|
40586
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40520
40587
|
} catch {}
|
|
40521
40588
|
await restart(e.selfId, e.contact, msgResult.messageId);
|
|
40522
40589
|
} else e.reply(`${Root.pluginName} 更新失败: ${result.data ?? "更新执行失败"}`);
|
|
@@ -40586,7 +40653,8 @@ var installAndRestart = async (e, version) => {
|
|
|
40586
40653
|
const msgResult = await e.reply(`${Root.pluginName} 更新成功!→ ${version}\n开始执行重启......`);
|
|
40587
40654
|
if (msgResult.messageId) try {
|
|
40588
40655
|
await db.del(UPDATE_MSGID_KEY);
|
|
40589
|
-
await db.del(
|
|
40656
|
+
await db.del(UPDATE_PUSHED_KEY);
|
|
40657
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40590
40658
|
} catch {}
|
|
40591
40659
|
await restart(e.selfId, e.contact, msgResult.messageId);
|
|
40592
40660
|
};
|
|
@@ -40743,7 +40811,8 @@ var kkkUpdateCommand = karin.command(/^#?kkk更新(?:\s*(\S+))?$/, handleKkkUpda
|
|
|
40743
40811
|
});
|
|
40744
40812
|
var kkkUpdateTest = process.env.NODE_ENV === "development" && karin.command("test", async (_e, next) => {
|
|
40745
40813
|
await db.del(UPDATE_MSGID_KEY);
|
|
40746
|
-
await db.del(
|
|
40814
|
+
await db.del(UPDATE_PUSHED_KEY);
|
|
40815
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40747
40816
|
await Handler();
|
|
40748
40817
|
next();
|
|
40749
40818
|
}, { name: "kkk-更新检测-测试" });
|
|
@@ -41716,7 +41785,7 @@ app$1.use(ASSETS_PREFIX, staticRouter);
|
|
|
41716
41785
|
app.use(KKK_PREFIX, app$1);
|
|
41717
41786
|
//#endregion
|
|
41718
41787
|
//#region src/setup.ts
|
|
41719
|
-
var requireVersion = "1.
|
|
41788
|
+
var requireVersion = "1.18.0";
|
|
41720
41789
|
if (process.env.NODE_ENV !== "development" && isSemverGreater(requireVersion, Root.karinVersion)) {
|
|
41721
41790
|
const msg = `插件构建时的 karin 版本 (${requireVersion}) 高于当前运行版本 (${Root.karinVersion}),可能会出现兼容性问题!`;
|
|
41722
41791
|
logger$1.warn(msg);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "karin-plugin-kkk",
|
|
3
|
-
"version": "2.45.0-beta.
|
|
3
|
+
"version": "2.45.0-beta.5",
|
|
4
4
|
"description": "Karin 的「抖音」「B 站」视频解析/动态推送插件",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"karin",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@lobehub/webfont-harmony-sans-sc": "^1.0.0",
|
|
84
84
|
"emoji-datasource-apple": "16.0.0"
|
|
85
85
|
},
|
|
86
|
-
"timestamp": "2026-10-
|
|
86
|
+
"timestamp": "2026-10-06T08:24:09.485Z",
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=18.0.0"
|
|
89
89
|
}
|