fix(agents): import standalone JRE offline packages
This commit is contained in:
20 files changed
+306
-13
No files matched your search
@@ -744,9 +744,9 @@ async function importOfflineZip() {
|
||||
activeAgentOperationId.value = uuid();
|
||||
resetAgentInstallProgress();
|
||||
try {
|
||||
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||
const result = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||
await Promise.all([refreshAgents(), loadJdbcDrivers(), loadJdbcPluginStatus()]);
|
||||
toast(t("driverStore.offlineImportSuccess", { count }));
|
||||
toast(t(result.jreCount > 0 ? (result.count > 0 ? "driverStore.offlineImportWithJreSuccess" : "driverStore.offlineJreImportSuccess") : "driverStore.offlineImportSuccess", { count: result.count, jreCount: result.jreCount }));
|
||||
} catch (e: any) {
|
||||
toast(t("driverStore.offlineImportFailed", { error: backendError(e) }));
|
||||
} finally {
|
||||
@@ -776,9 +776,9 @@ async function importDriverFile(driver: AgentDriverInfo) {
|
||||
activeAgentOperationId.value = uuid();
|
||||
resetAgentInstallProgress();
|
||||
try {
|
||||
const count = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||
const result = await api.importAgentsFromZip(selected, activeAgentOperationId.value);
|
||||
await Promise.all([refreshAgents(), loadJdbcDrivers(), loadJdbcPluginStatus()]);
|
||||
toast(t("driverStore.offlineImportSuccess", { count }));
|
||||
toast(t(result.jreCount > 0 ? (result.count > 0 ? "driverStore.offlineImportWithJreSuccess" : "driverStore.offlineJreImportSuccess") : "driverStore.offlineImportSuccess", { count: result.count, jreCount: result.jreCount }));
|
||||
} finally {
|
||||
activeAgentOperationId.value = null;
|
||||
resetAgentInstallProgress();
|
||||
|
||||
@@ -7861,6 +7861,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} drayverini silmək mümkün olmadı: {error}",
|
||||
chooseOfflineDriverPackage: "Oflayn drayver paketini seç",
|
||||
offlineImportSuccess: "Oflayn idxal tamamlandı. {count} drayver quraşdırıldı.",
|
||||
offlineJreImportSuccess: "Oflayn idxal tamamlandı. {jreCount} JRE quraşdırıldı.",
|
||||
offlineImportWithJreSuccess: "Oflayn idxal tamamlandı. {jreCount} JRE və {count} drayver quraşdırıldı.",
|
||||
offlineImportFailed: "Oflayn idxal uğursuz oldu: {error}",
|
||||
driverImportSuccess: "{label} drayveri idxal edildi",
|
||||
driverImportFailed: "{label} drayverini idxal etmək mümkün olmadı: {error}",
|
||||
|
||||
@@ -8051,6 +8051,8 @@ export default {
|
||||
driverUninstallFailed: "Failed to uninstall {label} driver: {error}",
|
||||
chooseOfflineDriverPackage: "Choose offline driver package",
|
||||
offlineImportSuccess: "Offline import complete. Installed {count} driver(s).",
|
||||
offlineJreImportSuccess: "Offline import complete. Installed {jreCount} JRE(s).",
|
||||
offlineImportWithJreSuccess: "Offline import complete. Installed {jreCount} JRE(s) and {count} driver(s).",
|
||||
offlineImportFailed: "Offline import failed: {error}",
|
||||
driverImportSuccess: "{label} driver imported",
|
||||
driverImportFailed: "Failed to import {label} driver: {error}",
|
||||
|
||||
@@ -7599,6 +7599,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "Error al desinstalar el driver {label}: {error}",
|
||||
chooseOfflineDriverPackage: "Seleccionar paquete offline de drivers",
|
||||
offlineImportSuccess: "Importación offline completada. Se instalaron {count} driver(s).",
|
||||
offlineJreImportSuccess: "Importación offline completada. Se instalaron {jreCount} JRE(s).",
|
||||
offlineImportWithJreSuccess: "Importación offline completada. Se instalaron {jreCount} JRE(s) y {count} driver(s).",
|
||||
offlineImportFailed: "Error en la importación offline: {error}",
|
||||
driverImportSuccess: "Driver {label} importado",
|
||||
driverImportFailed: "Error al importar el driver {label}: {error}",
|
||||
|
||||
@@ -7599,6 +7599,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "Disinstillazione del driver {label} non riuscita: {error}",
|
||||
chooseOfflineDriverPackage: "Scegli pacchetto driver offline",
|
||||
offlineImportSuccess: "Importazione offline completata. Installato/i {count} driver.",
|
||||
offlineJreImportSuccess: "Importazione offline completata. Installato/i {jreCount} JRE.",
|
||||
offlineImportWithJreSuccess: "Importazione offline completata. Installato/i {jreCount} JRE e {count} driver.",
|
||||
offlineImportFailed: "Importazione offline non riuscita: {error}",
|
||||
driverImportSuccess: "Driver {label} importato",
|
||||
driverImportFailed: "Importazione del driver {label} non riuscita: {error}",
|
||||
|
||||
@@ -7651,6 +7651,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} ドライバーのアンインストールに失敗しました: {error}",
|
||||
chooseOfflineDriverPackage: "オフラインドライバーパッケージを選択",
|
||||
offlineImportSuccess: "オフラインインポートが完了しました。{count}件のドライバーをインストールしました。",
|
||||
offlineJreImportSuccess: "オフラインインポートが完了しました。{jreCount}件のJREをインストールしました。",
|
||||
offlineImportWithJreSuccess: "オフラインインポートが完了しました。{jreCount}件のJREと{count}件のドライバーをインストールしました。",
|
||||
offlineImportFailed: "オフラインインポートに失敗しました: {error}",
|
||||
driverImportSuccess: "{label} ドライバーをインポートしました",
|
||||
driverImportFailed: "{label} ドライバーのインポートに失敗しました: {error}",
|
||||
|
||||
@@ -7331,6 +7331,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} 드라이버 제거 실패: {error}",
|
||||
chooseOfflineDriverPackage: "오프라인 드라이버 패키지 선택",
|
||||
offlineImportSuccess: "오프라인 가져오기 완료. 드라이버 {count}개 설치.",
|
||||
offlineJreImportSuccess: "오프라인 가져오기 완료. JRE {jreCount}개 설치.",
|
||||
offlineImportWithJreSuccess: "오프라인 가져오기 완료. JRE {jreCount}개와 드라이버 {count}개 설치.",
|
||||
offlineImportFailed: "오프라인 가져오기 실패: {error}",
|
||||
driverImportSuccess: "{label} 드라이버를 가져왔습니다",
|
||||
driverImportFailed: "{label} 드라이버 가져오기 실패: {error}",
|
||||
|
||||
@@ -7601,6 +7601,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "Falha ao desinstalar o driver {label}: {error}",
|
||||
chooseOfflineDriverPackage: "Escolher pacote de driver offline",
|
||||
offlineImportSuccess: "Importação offline concluída. {count} driver(s) instalado(s).",
|
||||
offlineJreImportSuccess: "Importação offline concluída. {jreCount} JRE(s) instalado(s).",
|
||||
offlineImportWithJreSuccess: "Importação offline concluída. {jreCount} JRE(s) e {count} driver(s) instalado(s).",
|
||||
offlineImportFailed: "Falha na importação offline: {error}",
|
||||
driverImportSuccess: "Driver {label} importado",
|
||||
driverImportFailed: "Falha ao importar o driver {label}: {error}",
|
||||
|
||||
@@ -7713,6 +7713,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} sürücüsü kaldırılamadı: {error}",
|
||||
chooseOfflineDriverPackage: "Çevrimdışı sürücü paketini seçin",
|
||||
offlineImportSuccess: "Çevrimdışı içe aktarma tamamlandı. {count} sürücü kuruldu.",
|
||||
offlineJreImportSuccess: "Çevrimdışı içe aktarma tamamlandı. {jreCount} JRE kuruldu.",
|
||||
offlineImportWithJreSuccess: "Çevrimdışı içe aktarma tamamlandı. {jreCount} JRE ve {count} sürücü kuruldu.",
|
||||
offlineImportFailed: "Çevrimdışı içe aktarma başarısız: {error}",
|
||||
driverImportSuccess: "{label} sürücüsü içe aktarıldı",
|
||||
driverImportFailed: "{label} sürücüsü içe aktarılamadı: {error}",
|
||||
|
||||
@@ -8023,6 +8023,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} 驱动卸载失败: {error}",
|
||||
chooseOfflineDriverPackage: "选择离线驱动包",
|
||||
offlineImportSuccess: "离线导入完成,已安装 {count} 个驱动",
|
||||
offlineJreImportSuccess: "离线导入完成,已安装 {jreCount} 个 JRE",
|
||||
offlineImportWithJreSuccess: "离线导入完成,已安装 {jreCount} 个 JRE 和 {count} 个驱动",
|
||||
offlineImportFailed: "离线导入失败: {error}",
|
||||
driverImportSuccess: "{label} 驱动导入成功",
|
||||
driverImportFailed: "{label} 驱动导入失败: {error}",
|
||||
|
||||
@@ -6903,6 +6903,8 @@ export default withEnglishFallback({
|
||||
driverUninstallFailed: "{label} 驅動程式解除安裝失敗: {error}",
|
||||
chooseOfflineDriverPackage: "選擇離線驅動程式包",
|
||||
offlineImportSuccess: "離線匯入完成,已安裝 {count} 個驅動程式",
|
||||
offlineJreImportSuccess: "離線匯入完成,已安裝 {jreCount} 個 JRE",
|
||||
offlineImportWithJreSuccess: "離線匯入完成,已安裝 {jreCount} 個 JRE 和 {count} 個驅動程式",
|
||||
offlineImportFailed: "離線匯入失敗: {error}",
|
||||
driverImportSuccess: "{label} 驅動程式匯入成功",
|
||||
driverImportFailed: "{label} 驅動程式匯入失敗: {error}",
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mocks = vi.hoisted(() => ({ invoke: vi.fn() }));
|
||||
vi.mock("@tauri-apps/api/core", () => ({ invoke: mocks.invoke }));
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("offline Agent and standalone JRE import", () => {
|
||||
it("returns separate driver and JRE counts from the desktop command", async () => {
|
||||
const { importAgentsFromZip } = await import("../tauri");
|
||||
mocks.invoke.mockResolvedValue({ count: 0, jreCount: 1 });
|
||||
expect(await importAgentsFromZip("/tmp/renamed.tar.zst", "import-1")).toEqual({ count: 0, jreCount: 1 });
|
||||
expect(mocks.invoke).toHaveBeenCalledWith("import_agents_from_zip", { path: "/tmp/renamed.tar.zst", operationId: "import-1" });
|
||||
});
|
||||
|
||||
it("uploads standalone JRE packages and preserves both result counts", async () => {
|
||||
const fetchMock = vi.fn().mockResolvedValue(new Response(JSON.stringify({ count: 0, jreCount: 1 })));
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
const { importAgentsFromZip } = await import("../http");
|
||||
const file = new File(["archive"], "renamed.tar.zst");
|
||||
expect(await importAgentsFromZip(file, "import-2")).toEqual({ count: 0, jreCount: 1 });
|
||||
const [url, request] = fetchMock.mock.calls[0];
|
||||
expect(url).toContain("/api/agents/import-offline");
|
||||
expect(request.method).toBe("POST");
|
||||
expect(request.body.get("operationId")).toBe("import-2");
|
||||
expect(request.body.get("file").name).toBe(file.name);
|
||||
});
|
||||
|
||||
it("remains compatible with web backends that only return a driver count", async () => {
|
||||
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(new Response(JSON.stringify({ count: 2 }))));
|
||||
const { importAgentsFromZip } = await import("../http");
|
||||
expect(await importAgentsFromZip(new File(["archive"], "drivers.zip"))).toEqual({ count: 2, jreCount: 0 });
|
||||
});
|
||||
});
|
||||
@@ -69,6 +69,7 @@ import type {
|
||||
DriverStoreUsage,
|
||||
DriverRuntimeSummary,
|
||||
UpgradeAllAgentDriversResult,
|
||||
AgentOfflineImportResult,
|
||||
AgentUpdateBlocker,
|
||||
AgentOfflineExportPreview,
|
||||
AgentOfflineExportResult,
|
||||
@@ -861,7 +862,7 @@ export async function invalidateAgentRegistryCache(): Promise<void> {
|
||||
await post("/api/agents/invalidate-registry-cache", {});
|
||||
}
|
||||
|
||||
export async function importAgentsFromZip(fileOrPath: string | File, operationId?: string): Promise<number> {
|
||||
export async function importAgentsFromZip(fileOrPath: string | File, operationId?: string): Promise<AgentOfflineImportResult> {
|
||||
if (typeof fileOrPath === "string") {
|
||||
throw new Error("Offline package import in web mode requires a File object, not a file path");
|
||||
}
|
||||
@@ -873,8 +874,8 @@ export async function importAgentsFromZip(fileOrPath: string | File, operationId
|
||||
body: formData,
|
||||
});
|
||||
if (!res.ok) throw await backendResponseError(res);
|
||||
const result: { count: number } = await res.json();
|
||||
return result.count;
|
||||
const result: AgentOfflineImportResult = await res.json();
|
||||
return { count: result.count, jreCount: result.jreCount ?? 0 };
|
||||
}
|
||||
|
||||
export async function previewAgentOfflineExport(): Promise<AgentOfflineExportPreview> {
|
||||
|
||||
@@ -200,6 +200,11 @@ export interface AgentOfflineExportResult {
|
||||
bytes: number;
|
||||
}
|
||||
|
||||
export interface AgentOfflineImportResult {
|
||||
count: number;
|
||||
jreCount: number;
|
||||
}
|
||||
|
||||
export type JavaRuntimeMode = "managed" | "system" | "custom";
|
||||
|
||||
export interface JavaRuntimeConfig {
|
||||
@@ -2511,7 +2516,7 @@ export async function invalidateAgentRegistryCache(): Promise<void> {
|
||||
return invoke("invalidate_agent_registry_cache");
|
||||
}
|
||||
|
||||
export async function importAgentsFromZip(path: string | File, operationId?: string): Promise<number> {
|
||||
export async function importAgentsFromZip(path: string | File, operationId?: string): Promise<AgentOfflineImportResult> {
|
||||
if (typeof path !== "string") {
|
||||
throw new Error("Desktop offline package import requires a local file path");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user