mioku-service-webui 4.5.1 → 4.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mioku-service-webui",
3
- "version": "4.5.1",
3
+ "version": "4.6.0",
4
4
  "description": "Mioku WebUI 服务",
5
5
  "main": "index.ts",
6
6
  "type": "module",
package/routes/config.ts CHANGED
@@ -4,6 +4,8 @@ import {
4
4
  getMiokuConfig,
5
5
  updateMiokuConfig,
6
6
  getAvailablePlugins,
7
+ getPluginStatusList,
8
+ togglePlugin,
7
9
  checkMiokuReleaseUpdate,
8
10
  updateMiokuFromMain,
9
11
  } from "../system";
@@ -48,5 +50,20 @@ export function createConfigRoutes() {
48
50
  return c.json({ ok: true, data });
49
51
  });
50
52
 
53
+ app.get("/plugins", (c) => {
54
+ const data = getPluginStatusList();
55
+ return c.json({ ok: true, data });
56
+ });
57
+
58
+ app.post("/plugins/toggle", async (c) => {
59
+ const body = (await c.req.json()) as { name: string; enabled: boolean };
60
+ const data = togglePlugin(body.name, body.enabled);
61
+ logger.info(`[webui-action] config.plugins.toggle`, {
62
+ name: body.name,
63
+ enabled: body.enabled,
64
+ });
65
+ return c.json({ ok: true, data });
66
+ });
67
+
51
68
  return app;
52
69
  }
package/system.ts CHANGED
@@ -1213,9 +1213,46 @@ export async function removeManagedPackage(
1213
1213
  throw new Error("系统服务不可卸载");
1214
1214
  }
1215
1215
 
1216
- const dir = resolveManagedDir(input.target, input.name);
1216
+ // construct full package name from short name
1217
+ const fullName = input.name.startsWith("mioku-plugin-") || input.name.startsWith("mioku-service-")
1218
+ ? input.name
1219
+ : input.target === "plugin"
1220
+ ? `mioku-plugin-${input.name}`
1221
+ : `mioku-service-${input.name}`;
1222
+
1223
+ const installCmd = getInstallCommand();
1224
+ const removeArgs = installCmd.args.map((a) =>
1225
+ a === "add" ? "remove" : a,
1226
+ );
1227
+
1228
+ const result = await runCommand(
1229
+ installCmd.cmd,
1230
+ [...removeArgs, fullName],
1231
+ process.cwd(),
1232
+ );
1233
+
1234
+ if (result.code !== 0) {
1235
+ throw new Error(`bun remove 失败: ${result.stderr || result.stdout}`);
1236
+ }
1217
1237
 
1218
- fs.rmSync(dir, { recursive: true, force: true });
1238
+ // clean up mioki.plugins list for plugins
1239
+ if (input.target === "plugin") {
1240
+ const pkgPath = ROOT_PACKAGE_PATH;
1241
+ if (fs.existsSync(pkgPath)) {
1242
+ try {
1243
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
1244
+ const mioki = pkg.mioki ?? {};
1245
+ const plugins: string[] = Array.isArray(mioki.plugins) ? mioki.plugins : [];
1246
+ const shortName = fullName.replace(/^mioku-plugin-/, "");
1247
+ if (plugins.includes(shortName)) {
1248
+ pkg.mioki = { ...mioki, plugins: plugins.filter((p: string) => p !== shortName) };
1249
+ fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`);
1250
+ }
1251
+ } catch {
1252
+ // silently ignore package.json parse errors
1253
+ }
1254
+ }
1255
+ }
1219
1256
 
1220
1257
  managedPackageUpdateCache.delete(
1221
1258
  makeManagedUpdateCacheKey(input.target, input.name),
@@ -2349,3 +2386,53 @@ export function getAvailablePlugins(): string[] {
2349
2386
  }
2350
2387
  return plugins.sort((a, b) => a.localeCompare(b));
2351
2388
  }
2389
+
2390
+ export interface PluginStatusItem {
2391
+ name: string;
2392
+ enabled: boolean;
2393
+ system: boolean;
2394
+ description: string;
2395
+ }
2396
+
2397
+ export function getPluginStatusList(): PluginStatusItem[] {
2398
+ const allPlugins = getAvailablePlugins();
2399
+ const miokuConfig = getMiokuConfig();
2400
+ const enabledPlugins = new Set(miokuConfig.plugins || []);
2401
+
2402
+ return allPlugins.map((name) => {
2403
+ const fullPath = path.join(NODE_MODULES_DIR, `mioku-plugin-${name}`);
2404
+ const pkg = readPackageJson(fullPath);
2405
+ return {
2406
+ name,
2407
+ enabled: enabledPlugins.has(name),
2408
+ system: SYSTEM_PLUGIN_NAMES.has(name.toLowerCase()),
2409
+ description: pkg?.description ?? "",
2410
+ };
2411
+ });
2412
+ }
2413
+
2414
+ export function togglePlugin(name: string, enabled: boolean): PluginStatusItem {
2415
+ const safeName = String(name || "").trim();
2416
+ if (!safeName) throw new Error("插件名称为空");
2417
+
2418
+ const config = getMiokuConfig();
2419
+ const plugins = new Set(config.plugins || []);
2420
+
2421
+ if (enabled) {
2422
+ plugins.add(safeName);
2423
+ } else {
2424
+ if (safeName.toLowerCase() === "boot") {
2425
+ throw new Error("boot 插件不可关闭");
2426
+ }
2427
+ plugins.delete(safeName);
2428
+ }
2429
+
2430
+ updateMiokuConfig({ ...config, plugins: Array.from(plugins) });
2431
+
2432
+ return {
2433
+ name: safeName,
2434
+ enabled: plugins.has(safeName),
2435
+ system: SYSTEM_PLUGIN_NAMES.has(safeName.toLowerCase()),
2436
+ description: "",
2437
+ };
2438
+ }