mioku-service-webui 4.0.4 → 4.0.6

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.
Files changed (3) hide show
  1. package/index.ts +2 -1
  2. package/package.json +3 -1
  3. package/system.ts +38 -15
package/index.ts CHANGED
@@ -8,7 +8,7 @@ import { createNodeWebSocket } from "@hono/node-ws";
8
8
  import type { MiokuService } from "mioku";
9
9
  import type { WebUISettings } from "./types";
10
10
  import { ensureAuthConfig, loginWithToken, requireAuth } from "./auth";
11
- import { getWebUISettings, getSystemOverview, getSaying } from "./system";
11
+ import { ensureWebUIDist, getWebUISettings, getSystemOverview, getSaying } from "./system";
12
12
  import { CHAT_CONFIG_DIR, CHAT_DATA_DIR, LOGS_DIR, WEBUI_DIST } from "./utils";
13
13
  import { initBuiltinDatasources } from "./datasources";
14
14
  import {
@@ -220,6 +220,7 @@ const webUIService: MiokuService = {
220
220
  async init() {
221
221
  initBuiltinDatasources();
222
222
  ensureAuthConfig();
223
+ await ensureWebUIDist();
223
224
  runtime.initRoutes();
224
225
  },
225
226
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mioku-service-webui",
3
- "version": "4.0.4",
3
+ "version": "4.0.6",
4
4
  "description": "Mioku WebUI 服务",
5
5
  "main": "index.ts",
6
6
  "type": "module",
@@ -18,6 +18,8 @@
18
18
  "dependencies": {
19
19
  "@hono/node-server": "1.19.13",
20
20
  "@hono/node-ws": "^1.2.0",
21
+ "@types/adm-zip": "^0.5.8",
22
+ "adm-zip": "^0.5.16",
21
23
  "fflate": "^0.8.2",
22
24
  "gray-matter": "^4.0.3",
23
25
  "hono": "4.12.14"
package/system.ts CHANGED
@@ -2,7 +2,8 @@ import * as fs from "node:fs";
2
2
  import * as os from "node:os";
3
3
  import * as path from "node:path";
4
4
  import process from "node:process";
5
- import { connectedBots, systemInfo } from "mioki";
5
+ import AdmZip from "adm-zip";
6
+ import { connectedBots, logger, systemInfo } from "mioki";
6
7
  import type {
7
8
  InstallRequest,
8
9
  ManagedTarget,
@@ -701,6 +702,7 @@ interface WebUIUpdateCheckResult {
701
702
  assetUrl: string;
702
703
  checkedAt: number;
703
704
  error?: string;
705
+ proxiedAssetUrl?: string;
704
706
  }
705
707
 
706
708
  interface MiokuUpdateCheckResult {
@@ -1568,6 +1570,9 @@ async function fetchLatestWebUIUpdate(
1568
1570
  hasUpdates && !distAsset
1569
1571
  ? "已检测到新版本,但 Release 没有可用 dist 压缩包"
1570
1572
  : "",
1573
+ proxiedAssetUrl: distAsset
1574
+ ? `https://gh-proxy.org/${encodeURIComponent(distAsset.browser_download_url)}`
1575
+ : "",
1571
1576
  };
1572
1577
  })();
1573
1578
 
@@ -1805,7 +1810,8 @@ export async function updateWebUIDistFromRelease(): Promise<
1805
1810
 
1806
1811
  let backupPath = "";
1807
1812
  try {
1808
- const downloadRes = await fetch(check.assetUrl, {
1813
+ const downloadUrl = check.proxiedAssetUrl || check.assetUrl;
1814
+ const downloadRes = await fetch(downloadUrl, {
1809
1815
  headers: {
1810
1816
  Accept: "application/octet-stream",
1811
1817
  "User-Agent": "mioku-webui-updater",
@@ -1819,16 +1825,8 @@ export async function updateWebUIDistFromRelease(): Promise<
1819
1825
  const buffer = Buffer.from(await downloadRes.arrayBuffer());
1820
1826
  fs.writeFileSync(zipPath, buffer);
1821
1827
 
1822
- await ensureUnzipCommand();
1823
-
1824
- const unzip = await runCommand(
1825
- "unzip",
1826
- ["-oq", zipPath, "-d", unpackDir],
1827
- process.cwd(),
1828
- );
1829
- if (unzip.code !== 0) {
1830
- throw new Error(`解压失败: ${unzip.stderr || unzip.stdout}`);
1831
- }
1828
+ const zip = new AdmZip(zipPath);
1829
+ zip.extractAllTo(unpackDir, true);
1832
1830
 
1833
1831
  const sourceDir = resolveDistSourceDir(unpackDir);
1834
1832
  if (!sourceDir) {
@@ -1893,6 +1891,16 @@ export async function updateWebUIDistFromRelease(): Promise<
1893
1891
  return task;
1894
1892
  }
1895
1893
 
1894
+ export async function ensureWebUIDist(): Promise<void> {
1895
+ // Skip if dist already exists and has usable files
1896
+ if (hasUsableDistFiles(WEBUI_DIST)) {
1897
+ return;
1898
+ }
1899
+ // Dist missing — trigger download
1900
+ logger.info("[webui] WebUI dist 未找到,正在下载...");
1901
+ await updateWebUIDistFromRelease();
1902
+ }
1903
+
1896
1904
  function readPackageVersion(filePath: string): string {
1897
1905
  try {
1898
1906
  if (!fs.existsSync(filePath)) return "unknown";
@@ -2240,7 +2248,22 @@ export function updateMiokuConfig(config: Partial<MiokuConfig>): MiokuConfig {
2240
2248
  }
2241
2249
 
2242
2250
  export function getAvailablePlugins(): string[] {
2243
- const rootPkg = readRootPackageJson();
2244
- const miokiConfig = rootPkg?.mioki || {};
2245
- return Array.isArray(miokiConfig.plugins) ? miokiConfig.plugins : [];
2251
+ const modulesPath = NODE_MODULES_DIR;
2252
+ if (!fs.existsSync(modulesPath)) {
2253
+ // Fallback to config-based reading
2254
+ const rootPkg = readRootPackageJson();
2255
+ const miokiConfig = rootPkg?.mioki || {};
2256
+ return Array.isArray(miokiConfig.plugins) ? miokiConfig.plugins : [];
2257
+ }
2258
+
2259
+ const plugins: string[] = [];
2260
+ const entries = fs.readdirSync(modulesPath, { withFileTypes: true });
2261
+ for (const entry of entries) {
2262
+ if (!entry.name.startsWith("mioku-plugin-")) continue;
2263
+ const fullPath = path.join(modulesPath, entry.name);
2264
+ const stat = fs.lstatSync(fullPath);
2265
+ if (!stat.isDirectory() && !stat.isSymbolicLink()) continue;
2266
+ plugins.push(entry.name.replace(/^mioku-plugin-/, ""));
2267
+ }
2268
+ return plugins.sort((a, b) => a.localeCompare(b));
2246
2269
  }