mioku 1.1.1 → 1.2.1
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/cli/index.cjs +318 -144
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +318 -144
- package/dist/cli/index.js.map +1 -1
- package/dist/{exec-CoLrq043.cjs → exec-B2fmdRh2.cjs} +80 -2
- package/dist/exec-B2fmdRh2.cjs.map +1 -0
- package/dist/{exec-vSS4BZ4z.js → exec-CBlGXt5y.js} +69 -3
- package/dist/exec-CBlGXt5y.js.map +1 -0
- package/dist/index.cjs +112 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -70
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/exec-CoLrq043.cjs.map +0 -1
- package/dist/exec-vSS4BZ4z.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_exec = require('./exec-
|
|
1
|
+
const require_exec = require('./exec-B2fmdRh2.cjs');
|
|
2
2
|
const node_fs = require_exec.__toESM(require("node:fs"));
|
|
3
3
|
const node_path = require_exec.__toESM(require("node:path"));
|
|
4
4
|
const node_url = require_exec.__toESM(require("node:url"));
|
|
@@ -3755,28 +3755,36 @@ function getInstalledVersion(pkgName) {
|
|
|
3755
3755
|
const pkg = readPackageJson$1(node_path.join(projectRoot(), "node_modules", pkgName));
|
|
3756
3756
|
return String(pkg?.version || "0.0.0");
|
|
3757
3757
|
}
|
|
3758
|
-
|
|
3759
|
-
|
|
3758
|
+
/** 项目 package.json 声明的 mioku 依赖,不含被 hoist 上来的传递依赖 */
|
|
3759
|
+
function listDeclaredPackages() {
|
|
3760
|
+
const pkg = readPackageJson$1(projectRoot());
|
|
3761
|
+
if (!pkg) return [];
|
|
3762
|
+
const deps = {
|
|
3763
|
+
...pkg.dependencies ?? {},
|
|
3764
|
+
...pkg.devDependencies ?? {},
|
|
3765
|
+
...pkg.optionalDependencies ?? {}
|
|
3766
|
+
};
|
|
3760
3767
|
const result = [];
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
for (const entry of entries) {
|
|
3764
|
-
const type = detectType(entry.name);
|
|
3768
|
+
for (const name of Object.keys(deps)) {
|
|
3769
|
+
const type = detectType(name);
|
|
3765
3770
|
if (!type) continue;
|
|
3766
|
-
const fullPath = node_path.join(
|
|
3767
|
-
const
|
|
3768
|
-
if (!
|
|
3769
|
-
const pkg = readPackageJson$1(fullPath);
|
|
3771
|
+
const fullPath = node_path.join(projectRoot(), "node_modules", name);
|
|
3772
|
+
const installed = readPackageJson$1(fullPath);
|
|
3773
|
+
if (!installed) continue;
|
|
3770
3774
|
result.push({
|
|
3771
|
-
name
|
|
3775
|
+
name,
|
|
3772
3776
|
type,
|
|
3773
|
-
shortName: shortNameOf(
|
|
3774
|
-
version: String(
|
|
3777
|
+
shortName: shortNameOf(name),
|
|
3778
|
+
version: String(installed.version || "0.0.0"),
|
|
3775
3779
|
path: fullPath
|
|
3776
3780
|
});
|
|
3777
3781
|
}
|
|
3778
3782
|
return result.sort((a, b) => a.name.localeCompare(b.name));
|
|
3779
3783
|
}
|
|
3784
|
+
/** .update all 的作用范围:声明的插件与服务,不含框架与传递依赖 */
|
|
3785
|
+
function listManagedPackages() {
|
|
3786
|
+
return listDeclaredPackages().filter((pkg) => pkg.type !== "framework");
|
|
3787
|
+
}
|
|
3780
3788
|
async function fetchJson(url) {
|
|
3781
3789
|
const res = await fetch(url, { headers: {
|
|
3782
3790
|
Accept: "application/json",
|
|
@@ -3788,8 +3796,13 @@ async function fetchJson(url) {
|
|
|
3788
3796
|
async function fetchNpmMeta(pkgName) {
|
|
3789
3797
|
try {
|
|
3790
3798
|
const data = await fetchJson(`${NPM_REGISTRY}/${encodeURIComponent(pkgName)}`);
|
|
3791
|
-
const
|
|
3792
|
-
const
|
|
3799
|
+
const versions = Object.keys(data?.versions ?? {});
|
|
3800
|
+
const distTag = String(data?.["dist-tags"]?.latest || "").trim();
|
|
3801
|
+
const staleTag = distTag !== "" && !versions.includes(distTag);
|
|
3802
|
+
const latest = staleTag ? require_exec.pickHighestVersion(versions) ?? distTag : distTag || (require_exec.pickHighestVersion(versions) ?? "");
|
|
3803
|
+
if (!latest) return null;
|
|
3804
|
+
if (staleTag) rootLogger.debug(`[core] ${pkgName} 的 latest 标签 ${distTag} 不存在,改用 ${latest}`);
|
|
3805
|
+
const version$2 = data?.versions?.[latest] || {};
|
|
3793
3806
|
const repository = version$2?.repository || data?.repository;
|
|
3794
3807
|
let repoUrl = "";
|
|
3795
3808
|
if (typeof repository === "string") repoUrl = repository;
|
|
@@ -3797,6 +3810,8 @@ async function fetchNpmMeta(pkgName) {
|
|
|
3797
3810
|
repoUrl = repoUrl.replace(/^git\+/, "").replace(/\.git$/, "");
|
|
3798
3811
|
return {
|
|
3799
3812
|
latest,
|
|
3813
|
+
distTag,
|
|
3814
|
+
staleTag,
|
|
3800
3815
|
description: String(version$2?.description || data?.description || "").trim(),
|
|
3801
3816
|
keywords: Array.isArray(version$2?.keywords) ? version$2.keywords : [],
|
|
3802
3817
|
homepage: String(version$2?.homepage || data?.homepage || "").trim(),
|
|
@@ -3809,7 +3824,7 @@ async function fetchNpmMeta(pkgName) {
|
|
|
3809
3824
|
}
|
|
3810
3825
|
}
|
|
3811
3826
|
async function checkUpdates() {
|
|
3812
|
-
const installed =
|
|
3827
|
+
const installed = listDeclaredPackages();
|
|
3813
3828
|
const metas = await Promise.all(installed.map(async (pkg) => {
|
|
3814
3829
|
const meta = await fetchNpmMeta(pkg.name);
|
|
3815
3830
|
return {
|
|
@@ -3820,7 +3835,7 @@ async function checkUpdates() {
|
|
|
3820
3835
|
const updates = [];
|
|
3821
3836
|
for (const { pkg, meta } of metas) {
|
|
3822
3837
|
if (!meta || !meta.latest) continue;
|
|
3823
|
-
if (meta.latest
|
|
3838
|
+
if (require_exec.compareVersions(meta.latest, pkg.version) <= 0) continue;
|
|
3824
3839
|
updates.push({
|
|
3825
3840
|
name: pkg.name,
|
|
3826
3841
|
type: pkg.type,
|
|
@@ -3831,53 +3846,72 @@ async function checkUpdates() {
|
|
|
3831
3846
|
}
|
|
3832
3847
|
return updates;
|
|
3833
3848
|
}
|
|
3849
|
+
/** 取 bun 输出里最有用的一行:优先 error: 行,去掉颜色与前缀,超长截断 */
|
|
3850
|
+
function errorSummary(text$1) {
|
|
3851
|
+
const lines = String(text$1 ?? "").replace(/\u001b\[[0-9;]*m/g, "").split("\n").map((line$1) => line$1.trim()).filter(Boolean);
|
|
3852
|
+
const line = (lines.find((item) => /^error:/i.test(item)) ?? lines[0] ?? "更新失败").replace(/^error:\s*/i, "");
|
|
3853
|
+
return line.length > 160 ? `${line.slice(0, 157)}...` : line;
|
|
3854
|
+
}
|
|
3834
3855
|
function snapshotVersions(names) {
|
|
3835
3856
|
const map = new Map();
|
|
3836
3857
|
for (const name of names) map.set(name, getInstalledVersion(name));
|
|
3837
3858
|
return map;
|
|
3838
3859
|
}
|
|
3860
|
+
function outcomeOf(name, before, ok = true, error) {
|
|
3861
|
+
const prev = before.get(name) ?? "0.0.0";
|
|
3862
|
+
const after = getInstalledVersion(name);
|
|
3863
|
+
return {
|
|
3864
|
+
name,
|
|
3865
|
+
ok,
|
|
3866
|
+
before: prev,
|
|
3867
|
+
after,
|
|
3868
|
+
changed: prev !== after,
|
|
3869
|
+
error
|
|
3870
|
+
};
|
|
3871
|
+
}
|
|
3872
|
+
/** latest 标签不可解析时,改用 npm 上真实存在的最高版本 */
|
|
3873
|
+
async function updateWithPinnedVersion(name) {
|
|
3874
|
+
const meta = await fetchNpmMeta(name);
|
|
3875
|
+
const target = meta?.latest ?? "";
|
|
3876
|
+
if (!target) return false;
|
|
3877
|
+
if (require_exec.compareVersions(target, getInstalledVersion(name)) <= 0) return true;
|
|
3878
|
+
rootLogger.info(`[core] ${name} 的 latest 标签不可用,改用 ${target} 更新`);
|
|
3879
|
+
const result = await runBun(["update", `${name}@${target}`]);
|
|
3880
|
+
return result.code === 0;
|
|
3881
|
+
}
|
|
3882
|
+
async function updateOne(name, before) {
|
|
3883
|
+
const single = await runBun([
|
|
3884
|
+
"update",
|
|
3885
|
+
name,
|
|
3886
|
+
"--latest"
|
|
3887
|
+
]);
|
|
3888
|
+
if (single.code === 0) return outcomeOf(name, before);
|
|
3889
|
+
if (await updateWithPinnedVersion(name)) return outcomeOf(name, before);
|
|
3890
|
+
return outcomeOf(name, before, false, errorSummary(single.stderr || single.stdout));
|
|
3891
|
+
}
|
|
3839
3892
|
async function updatePackages(names) {
|
|
3840
3893
|
if (names.length === 0) return {
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
stderr: ""
|
|
3894
|
+
outcomes: [],
|
|
3895
|
+
failures: []
|
|
3844
3896
|
};
|
|
3845
|
-
|
|
3897
|
+
const before = snapshotVersions(names);
|
|
3898
|
+
const batch = await runBun([
|
|
3846
3899
|
"update",
|
|
3847
3900
|
...names,
|
|
3848
3901
|
"--latest"
|
|
3849
3902
|
]);
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
if (managed.length === 0) return {
|
|
3854
|
-
result: {
|
|
3855
|
-
code: 0,
|
|
3856
|
-
stdout: "",
|
|
3857
|
-
stderr: ""
|
|
3858
|
-
},
|
|
3859
|
-
names: []
|
|
3903
|
+
if (batch.code === 0) return {
|
|
3904
|
+
outcomes: names.map((name) => outcomeOf(name, before)),
|
|
3905
|
+
failures: []
|
|
3860
3906
|
};
|
|
3907
|
+
rootLogger.warn(`[core] 批量更新失败,改为逐个更新: ${errorSummary(batch.stderr || batch.stdout)}`);
|
|
3908
|
+
const outcomes = [];
|
|
3909
|
+
for (const name of names) outcomes.push(await updateOne(name, before));
|
|
3861
3910
|
return {
|
|
3862
|
-
|
|
3863
|
-
|
|
3911
|
+
outcomes,
|
|
3912
|
+
failures: outcomes.filter((outcome) => !outcome.ok)
|
|
3864
3913
|
};
|
|
3865
3914
|
}
|
|
3866
|
-
function diffVersions(names, before) {
|
|
3867
|
-
return names.map((name) => {
|
|
3868
|
-
const after = getInstalledVersion(name);
|
|
3869
|
-
const prev = before.get(name) || "0.0.0";
|
|
3870
|
-
return {
|
|
3871
|
-
name,
|
|
3872
|
-
before: prev,
|
|
3873
|
-
after,
|
|
3874
|
-
changed: prev !== after
|
|
3875
|
-
};
|
|
3876
|
-
});
|
|
3877
|
-
}
|
|
3878
|
-
function snapshotAll(names) {
|
|
3879
|
-
return snapshotVersions(names);
|
|
3880
|
-
}
|
|
3881
3915
|
function appendToMiokuPlugins(pkgName) {
|
|
3882
3916
|
if (!pkgName.startsWith(PLUGIN_PREFIX)) return false;
|
|
3883
3917
|
const shortName = pkgName.slice(PLUGIN_PREFIX.length);
|
|
@@ -3998,8 +4032,10 @@ function buildMarketItem(pkgName, meta, official) {
|
|
|
3998
4032
|
}
|
|
3999
4033
|
async function getMarketItems(type) {
|
|
4000
4034
|
const registry = await fetchOfficialRegistry();
|
|
4001
|
-
const
|
|
4035
|
+
const registryKey = type === "plugin" ? "plugins" : "services";
|
|
4036
|
+
const officialEntries = registry[registryKey] || {};
|
|
4002
4037
|
const officialNpmNames = new Set(Object.values(officialEntries).map((entry) => String(entry?.npm || "")).filter(Boolean));
|
|
4038
|
+
const hiddenShorts = new Set(registry.hidden?.[registryKey] ?? []);
|
|
4003
4039
|
const searchObjects = await searchNpmPackages().catch(() => []);
|
|
4004
4040
|
const prefix = type === "plugin" ? PLUGIN_PREFIX : SERVICE_PREFIX;
|
|
4005
4041
|
const candidateNames = new Set();
|
|
@@ -4008,6 +4044,7 @@ async function getMarketItems(type) {
|
|
|
4008
4044
|
if (name.startsWith(prefix)) candidateNames.add(name);
|
|
4009
4045
|
}
|
|
4010
4046
|
for (const name of officialNpmNames) if (name.startsWith(prefix)) candidateNames.add(name);
|
|
4047
|
+
for (const name of Array.from(candidateNames)) if (hiddenShorts.has(name.slice(prefix.length))) candidateNames.delete(name);
|
|
4011
4048
|
const metas = await Promise.all(Array.from(candidateNames).map(async (pkgName) => {
|
|
4012
4049
|
const meta = await fetchNpmMeta(pkgName);
|
|
4013
4050
|
return {
|
|
@@ -4239,24 +4276,27 @@ async function performUpdateAndReport(ctx, event, names) {
|
|
|
4239
4276
|
await replyText(event, "没有需要更新的项。");
|
|
4240
4277
|
return;
|
|
4241
4278
|
}
|
|
4242
|
-
const before = snapshotAll(names);
|
|
4243
4279
|
await replyText(event, `正在更新 ${names.length} 个包,请稍候...`);
|
|
4244
|
-
const
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4280
|
+
const report = await updatePackages(names);
|
|
4281
|
+
const changed = report.outcomes.filter((item) => item.changed);
|
|
4282
|
+
const failures = report.failures;
|
|
4283
|
+
ctx.logger.info(`[core] 更新结束:升级 ${changed.length} 个,失败 ${failures.length} 个`);
|
|
4284
|
+
if (failures.length > 0) ctx.logger.error(`[core] 更新失败: ${failures.map((item) => `${item.name}(${item.error})`).join("; ")}`);
|
|
4285
|
+
if (changed.length === 0 && failures.length === 0) {
|
|
4286
|
+
await replyText(event, "更新完成,所有包均已是最新版本");
|
|
4248
4287
|
return;
|
|
4249
4288
|
}
|
|
4250
|
-
const
|
|
4251
|
-
|
|
4252
|
-
|
|
4289
|
+
const parts = [];
|
|
4290
|
+
if (changed.length > 0) {
|
|
4291
|
+
parts.push(`更新完成,共 ${changed.length} 个包已升级:`, ...changed.map((item) => `• ${item.name}: ${item.before} → ${item.after}`));
|
|
4292
|
+
const unchanged = report.outcomes.length - changed.length - failures.length;
|
|
4293
|
+
if (unchanged > 0) parts.push("", `另有 ${unchanged} 个包已是最新`);
|
|
4294
|
+
}
|
|
4295
|
+
if (failures.length > 0) parts.push("", `以下 ${failures.length} 个包未能更新:`, ...failures.map((item) => `• ${item.name}: ${item.error}`), "", "通常是 npm 上的版本信息尚未同步,可稍后重试");
|
|
4253
4296
|
if (changed.length === 0) {
|
|
4254
|
-
await replyText(event, "
|
|
4297
|
+
await replyText(event, parts.join("\n"));
|
|
4255
4298
|
return;
|
|
4256
4299
|
}
|
|
4257
|
-
const lines = changed.map((d) => `• ${d.name}: ${d.before} → ${d.after}`);
|
|
4258
|
-
const parts = [`更新完成,共 ${changed.length} 个包已升级:`, ...lines];
|
|
4259
|
-
if (unchanged.length > 0) parts.push("", `另有 ${unchanged.length} 个包已是最新`);
|
|
4260
4300
|
parts.push("", "即将重启...");
|
|
4261
4301
|
await replyText(event, parts.join("\n"));
|
|
4262
4302
|
const selfId = String(event?.self_id ?? "");
|
|
@@ -4285,12 +4325,12 @@ function registerUpdateCommands(ctx) {
|
|
|
4285
4325
|
const bot = event.bot;
|
|
4286
4326
|
if (!bot) return;
|
|
4287
4327
|
if (arg === "all") {
|
|
4288
|
-
const managed =
|
|
4289
|
-
if (managed.
|
|
4328
|
+
const managed = listManagedPackages();
|
|
4329
|
+
if (managed.length === 0) {
|
|
4290
4330
|
await replyText(event, "未找到可更新的 mioku 包");
|
|
4291
4331
|
return;
|
|
4292
4332
|
}
|
|
4293
|
-
await performUpdateAndReport(ctx, event, managed.
|
|
4333
|
+
await performUpdateAndReport(ctx, event, managed.map((item) => item.name));
|
|
4294
4334
|
return;
|
|
4295
4335
|
}
|
|
4296
4336
|
if (arg === "mioku" || arg === "self") {
|
|
@@ -4695,18 +4735,20 @@ function startAutoUpdateScheduler(enabled, time, frequency) {
|
|
|
4695
4735
|
running = true;
|
|
4696
4736
|
try {
|
|
4697
4737
|
rootLogger.info("[core] 自动更新开始...");
|
|
4698
|
-
const allInstalled =
|
|
4738
|
+
const allInstalled = listDeclaredPackages();
|
|
4699
4739
|
const names = allInstalled.map((pkg) => pkg.name);
|
|
4700
4740
|
if (names.length === 0) {
|
|
4701
4741
|
rootLogger.info("[core] 未找到需要更新的包");
|
|
4702
4742
|
return;
|
|
4703
4743
|
}
|
|
4704
|
-
const
|
|
4705
|
-
|
|
4706
|
-
|
|
4744
|
+
const report = await updatePackages(names);
|
|
4745
|
+
const changed = report.outcomes.filter((item) => item.changed);
|
|
4746
|
+
if (report.failures.length > 0) rootLogger.error(`[core] 自动更新失败: ${report.failures.map((item) => `${item.name}(${item.error})`).join("; ")}`);
|
|
4747
|
+
if (changed.length === 0) {
|
|
4748
|
+
rootLogger.info("[core] 自动更新结束,没有包需要升级");
|
|
4707
4749
|
return;
|
|
4708
4750
|
}
|
|
4709
|
-
rootLogger.info(
|
|
4751
|
+
rootLogger.info(`[core] 自动更新成功,升级 ${changed.length} 个包,准备重启...`);
|
|
4710
4752
|
const marker = {
|
|
4711
4753
|
initiatedAt: Date.now(),
|
|
4712
4754
|
selfId: "",
|