mioku-service-webui 4.0.5 → 4.0.7
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/index.ts +2 -1
- package/package.json +3 -1
- package/system.ts +56 -12
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.
|
|
3
|
+
"version": "4.0.7",
|
|
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
|
|
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
|
|
|
@@ -1793,6 +1798,9 @@ export async function updateWebUIDistFromRelease(): Promise<
|
|
|
1793
1798
|
);
|
|
1794
1799
|
}
|
|
1795
1800
|
|
|
1801
|
+
let lastLogTime = 0;
|
|
1802
|
+
const LOG_INTERVAL_MS = 2000;
|
|
1803
|
+
const downloadUrl = new URL(check.assetUrl);
|
|
1796
1804
|
const tempDir = path.join(
|
|
1797
1805
|
os.tmpdir(),
|
|
1798
1806
|
`mioku-webui-update-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
@@ -1805,7 +1813,7 @@ export async function updateWebUIDistFromRelease(): Promise<
|
|
|
1805
1813
|
|
|
1806
1814
|
let backupPath = "";
|
|
1807
1815
|
try {
|
|
1808
|
-
const downloadRes = await fetch(
|
|
1816
|
+
const downloadRes = await fetch(downloadUrl, {
|
|
1809
1817
|
headers: {
|
|
1810
1818
|
Accept: "application/octet-stream",
|
|
1811
1819
|
"User-Agent": "mioku-webui-updater",
|
|
@@ -1816,20 +1824,46 @@ export async function updateWebUIDistFromRelease(): Promise<
|
|
|
1816
1824
|
throw new Error(`下载 dist 压缩包失败: HTTP_${downloadRes.status}`);
|
|
1817
1825
|
}
|
|
1818
1826
|
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1827
|
+
const contentLength = Number(downloadRes.headers.get("content-length") || 0);
|
|
1828
|
+
const reader = downloadRes.body?.getReader();
|
|
1829
|
+
if (!reader) {
|
|
1830
|
+
throw new Error("无法读取下载流");
|
|
1831
|
+
}
|
|
1821
1832
|
|
|
1822
|
-
|
|
1833
|
+
const chunks: Buffer[] = [];
|
|
1834
|
+
let receivedBytes = 0;
|
|
1823
1835
|
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1836
|
+
while (true) {
|
|
1837
|
+
const { done, value } = await reader.read();
|
|
1838
|
+
if (done) break;
|
|
1839
|
+
|
|
1840
|
+
if (value) {
|
|
1841
|
+
chunks.push(Buffer.from(value));
|
|
1842
|
+
receivedBytes += value.length;
|
|
1843
|
+
|
|
1844
|
+
if (contentLength > 0) {
|
|
1845
|
+
const now = Date.now();
|
|
1846
|
+
if (now - lastLogTime >= LOG_INTERVAL_MS) {
|
|
1847
|
+
const progress = Math.round((receivedBytes / contentLength) * 100);
|
|
1848
|
+
logger.info(`[webui] 正在下载 WebUI dist... ${receivedBytes}/${contentLength} bytes (${progress}%)`);
|
|
1849
|
+
lastLogTime = now;
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
if (contentLength > 0 && receivedBytes !== contentLength) {
|
|
1856
|
+
logger.warn(`[webui] 下载字节数不匹配: 预期 ${contentLength}, 实际 ${receivedBytes}`);
|
|
1831
1857
|
}
|
|
1832
1858
|
|
|
1859
|
+
logger.info(`[webui] 下载完成,正在解压...`);
|
|
1860
|
+
|
|
1861
|
+
const buffer = Buffer.concat(chunks);
|
|
1862
|
+
fs.writeFileSync(zipPath, buffer);
|
|
1863
|
+
|
|
1864
|
+
const zip = new AdmZip(zipPath);
|
|
1865
|
+
zip.extractAllTo(unpackDir, true);
|
|
1866
|
+
|
|
1833
1867
|
const sourceDir = resolveDistSourceDir(unpackDir);
|
|
1834
1868
|
if (!sourceDir) {
|
|
1835
1869
|
throw new Error("压缩包内未找到可用的 WebUI dist 文件");
|
|
@@ -1893,6 +1927,16 @@ export async function updateWebUIDistFromRelease(): Promise<
|
|
|
1893
1927
|
return task;
|
|
1894
1928
|
}
|
|
1895
1929
|
|
|
1930
|
+
export async function ensureWebUIDist(): Promise<void> {
|
|
1931
|
+
// Skip if dist already exists and has usable files
|
|
1932
|
+
if (hasUsableDistFiles(WEBUI_DIST)) {
|
|
1933
|
+
return;
|
|
1934
|
+
}
|
|
1935
|
+
// Dist missing — trigger download
|
|
1936
|
+
logger.info("[webui] WebUI dist 未找到,正在下载...");
|
|
1937
|
+
await updateWebUIDistFromRelease();
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1896
1940
|
function readPackageVersion(filePath: string): string {
|
|
1897
1941
|
try {
|
|
1898
1942
|
if (!fs.existsSync(filePath)) return "unknown";
|