karin-plugin-kkk 2.45.0-beta.3 → 2.45.0-beta.4
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 +8 -0
- package/lib/build-metadata.json +5 -5
- package/lib/core_chunk/main.js +84 -33
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [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)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### 🐛 错误修复
|
|
9
|
+
|
|
10
|
+
* 优化更新检测逻辑,支持逐渠道版本锁定与提醒 ([ddfd011](https://github.com/ikenxuan/karin-plugin-kkk/commit/ddfd011ac3bcd49789870a2e154003973c52cea9))
|
|
11
|
+
* 优化更新逻辑以支持金丝雀用户的版本解锁和范围起点解析 ([4a28ce5](https://github.com/ikenxuan/karin-plugin-kkk/commit/4a28ce55b82115683713ad6985d456751f151c23))
|
|
12
|
+
|
|
5
13
|
## [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
14
|
|
|
7
15
|
|
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.4",
|
|
3
|
+
"buildTime": "2026-10-06T07:34:14.563Z",
|
|
4
|
+
"buildTimestamp": 1791272054563,
|
|
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": "e6ff6df77f6305256a35f531a2f0c26f95fa3341",
|
|
9
|
+
"shortCommitHash": "e6ff6df7"
|
|
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,55 @@ 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";
|
|
40433
40477
|
/**
|
|
40434
40478
|
* 定时更新检测处理器
|
|
40435
|
-
*
|
|
40436
|
-
*
|
|
40479
|
+
* 逐渠道检查远程 dist-tag 版本:检测到该渠道有新版本就推送一次然后上锁,
|
|
40480
|
+
* 各渠道锁相互独立、互不挤占;金丝雀安装按构建时间线判定新版本。
|
|
40437
40481
|
*
|
|
40438
40482
|
* @returns 是否继续后续任务
|
|
40439
40483
|
*/
|
|
40440
40484
|
var Handler = async () => {
|
|
40441
|
-
const
|
|
40485
|
+
const channels = Config.app.UpdateNotifyChannels?.length ? Config.app.UpdateNotifyChannels : ["stable"];
|
|
40486
|
+
const tagOf = (c) => c === "stable" ? "latest" : c;
|
|
40442
40487
|
const installedIsCanary = parseReleaseChannel(Root.pluginVersion) === "Canary";
|
|
40443
40488
|
const installedBuildTime = getBuildMetadata()?.buildTimestamp;
|
|
40444
|
-
const
|
|
40489
|
+
const tagVersions = /* @__PURE__ */ new Map();
|
|
40490
|
+
await Promise.all([...new Set(channels.map(tagOf))].map(async (tag) => {
|
|
40445
40491
|
try {
|
|
40446
|
-
|
|
40492
|
+
tagVersions.set(tag, await getRemotePkgVersion(Root.pluginName, tag) || null);
|
|
40447
40493
|
} catch {
|
|
40448
|
-
|
|
40494
|
+
tagVersions.set(tag, null);
|
|
40449
40495
|
}
|
|
40450
40496
|
}));
|
|
40451
40497
|
const canaryInfo = installedIsCanary ? await fetchCanaryInfo() : null;
|
|
40452
|
-
const
|
|
40498
|
+
const isNewVersion = (version) => {
|
|
40453
40499
|
if (installedIsCanary && installedBuildTime !== void 0) {
|
|
40454
40500
|
const releaseNode = canaryInfo?.nodes.find((n) => n.message.includes(version));
|
|
40455
40501
|
if (releaseNode) return releaseNode.time > installedBuildTime;
|
|
40456
40502
|
}
|
|
40457
40503
|
return isSemverGreater(version, Root.pluginVersion);
|
|
40458
|
-
}
|
|
40459
|
-
|
|
40460
|
-
|
|
40461
|
-
const
|
|
40462
|
-
if (
|
|
40463
|
-
|
|
40464
|
-
|
|
40465
|
-
|
|
40466
|
-
|
|
40467
|
-
|
|
40468
|
-
|
|
40469
|
-
}
|
|
40504
|
+
};
|
|
40505
|
+
const pending = /* @__PURE__ */ new Set();
|
|
40506
|
+
for (const channel of channels) {
|
|
40507
|
+
const version = tagVersions.get(tagOf(channel)) ?? null;
|
|
40508
|
+
if (!version || !isNewVersion(version)) continue;
|
|
40509
|
+
try {
|
|
40510
|
+
const locked = await db.get(updateLockKey(channel));
|
|
40511
|
+
if (typeof locked === "string" && locked === version) continue;
|
|
40512
|
+
await db.set(updateLockKey(channel), version);
|
|
40513
|
+
} catch {}
|
|
40514
|
+
pending.add(version);
|
|
40515
|
+
}
|
|
40516
|
+
if (pending.size === 0) return true;
|
|
40470
40517
|
const masters = config.master().filter((id) => id !== "console");
|
|
40471
40518
|
if (masters.length === 0) return true;
|
|
40472
40519
|
const botItems = karin.getAllBotList().filter((b) => b.bot.account.name !== "console");
|
|
@@ -40486,12 +40533,16 @@ var Handler = async () => {
|
|
|
40486
40533
|
const botToImage = /* @__PURE__ */ new Map();
|
|
40487
40534
|
for (const item of botItems) {
|
|
40488
40535
|
if (!Array.from(masterToBot.entries()).some(([, b]) => b.account.selfId === item.bot.account.selfId)) continue;
|
|
40489
|
-
const
|
|
40490
|
-
|
|
40491
|
-
|
|
40492
|
-
|
|
40493
|
-
|
|
40494
|
-
|
|
40536
|
+
const elements = [segment.text("karin-plugin-kkk 有新的更新!")];
|
|
40537
|
+
for (const version of pending) {
|
|
40538
|
+
const img = await getChangelogImage({ bot: item.bot }, {
|
|
40539
|
+
localVersion: Root.pluginVersion,
|
|
40540
|
+
remoteVersion: version,
|
|
40541
|
+
Tip: true
|
|
40542
|
+
});
|
|
40543
|
+
if (img && img.length > 0) elements.push(...img);
|
|
40544
|
+
}
|
|
40545
|
+
if (elements.length > 1) botToImage.set(item.bot.account.selfId, elements);
|
|
40495
40546
|
}
|
|
40496
40547
|
let storedMsgId;
|
|
40497
40548
|
for (const owner of masters) {
|
|
@@ -40516,7 +40567,7 @@ var handleUpdateHook = wrapWithErrorHandler(async (e) => {
|
|
|
40516
40567
|
const msgResult = await e.reply(`${Root.pluginName} 更新成功!\n${result.local} -> ${result.remote}\n开始执行重启......`);
|
|
40517
40568
|
if (msgResult.messageId) try {
|
|
40518
40569
|
await db.del(UPDATE_MSGID_KEY);
|
|
40519
|
-
await db.del(
|
|
40570
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40520
40571
|
} catch {}
|
|
40521
40572
|
await restart(e.selfId, e.contact, msgResult.messageId);
|
|
40522
40573
|
} else e.reply(`${Root.pluginName} 更新失败: ${result.data ?? "更新执行失败"}`);
|
|
@@ -40586,7 +40637,7 @@ var installAndRestart = async (e, version) => {
|
|
|
40586
40637
|
const msgResult = await e.reply(`${Root.pluginName} 更新成功!→ ${version}\n开始执行重启......`);
|
|
40587
40638
|
if (msgResult.messageId) try {
|
|
40588
40639
|
await db.del(UPDATE_MSGID_KEY);
|
|
40589
|
-
await db.del(
|
|
40640
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40590
40641
|
} catch {}
|
|
40591
40642
|
await restart(e.selfId, e.contact, msgResult.messageId);
|
|
40592
40643
|
};
|
|
@@ -40743,7 +40794,7 @@ var kkkUpdateCommand = karin.command(/^#?kkk更新(?:\s*(\S+))?$/, handleKkkUpda
|
|
|
40743
40794
|
});
|
|
40744
40795
|
var kkkUpdateTest = process.env.NODE_ENV === "development" && karin.command("test", async (_e, next) => {
|
|
40745
40796
|
await db.del(UPDATE_MSGID_KEY);
|
|
40746
|
-
await db.del(
|
|
40797
|
+
for (const ch of UPDATE_CHANNELS) await db.del(updateLockKey(ch));
|
|
40747
40798
|
await Handler();
|
|
40748
40799
|
next();
|
|
40749
40800
|
}, { name: "kkk-更新检测-测试" });
|
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.4",
|
|
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-06T07:32:55.907Z",
|
|
87
87
|
"engines": {
|
|
88
88
|
"node": ">=18.0.0"
|
|
89
89
|
}
|