refactor(provider): complete prerequisite A ownership

This commit is contained in:
SaladDay
2026-08-01 08:37:49 +00:00
parent 2bc92e0f79
commit 37e78166c1
11 changed files with 667 additions and 264 deletions
+5 -1
View File
@@ -30,6 +30,7 @@ import {
supportsOfficialProxyTakeover,
} from "@/utils/providerCapabilities";
import { isOAuthProviderType } from "@/config/constants";
import { toProviderUpdateInput } from "@/lib/api/providers";
/**
* Hook for managing provider actions (add, update, delete, switch)
@@ -362,7 +363,10 @@ export function useProviderActions(
},
};
await providersApi.update(updatedProvider, activeApp);
await providersApi.update(
toProviderUpdateInput(updatedProvider),
activeApp,
);
await queryClient.invalidateQueries({
queryKey: ["providers", activeApp],
});
+40
View File
@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import type { Provider } from "@/types";
import { toProviderUpdateInput } from "./providers";
describe("toProviderUpdateInput", () => {
it("removes hydrated endpoints and row-state fields from update payloads", () => {
const hydrated: Provider = {
id: "endpoint-provider",
name: "Endpoint provider",
settingsConfig: { env: { API_KEY: "secret" } },
createdAt: 1_700_000_000,
sortIndex: 7,
inFailoverQueue: true,
meta: {
custom_endpoints: {
"https://one.example": {
url: "https://one.example",
addedAt: null,
},
},
usage_script: {
enabled: true,
language: "javascript",
code: "{}",
},
},
};
const update = toProviderUpdateInput(hydrated);
expect(update).not.toHaveProperty("createdAt");
expect(update).not.toHaveProperty("sortIndex");
expect(update).not.toHaveProperty("inFailoverQueue");
expect(update.meta).not.toHaveProperty("custom_endpoints");
expect(update.meta?.usage_script).toEqual(hydrated.meta?.usage_script);
expect(
hydrated.meta?.custom_endpoints?.["https://one.example"].addedAt,
).toBeNull();
});
});
+35 -1
View File
@@ -2,6 +2,7 @@ import { invoke } from "@tauri-apps/api/core";
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
import type {
Provider,
ProviderMeta,
UniversalProvider,
UniversalProvidersMap,
} from "@/types";
@@ -12,6 +13,39 @@ export interface ProviderSortUpdate {
sortIndex: number;
}
export type ProviderUpdateMeta = Omit<ProviderMeta, "custom_endpoints"> & {
custom_endpoints?: never;
};
export type ProviderUpdateInput = Omit<
Provider,
"createdAt" | "sortIndex" | "inFailoverQueue" | "meta"
> & {
meta?: ProviderUpdateMeta;
};
export function toProviderUpdateInput(provider: Provider): ProviderUpdateInput {
let meta: ProviderUpdateMeta | undefined;
if (provider.meta) {
const rowMeta = { ...provider.meta };
delete rowMeta.custom_endpoints;
meta = rowMeta as ProviderUpdateMeta;
}
return {
id: provider.id,
name: provider.name,
settingsConfig: provider.settingsConfig,
websiteUrl: provider.websiteUrl,
category: provider.category,
notes: provider.notes,
isPartner: provider.isPartner,
meta,
icon: provider.icon,
iconColor: provider.iconColor,
};
}
export interface ProviderSwitchEvent {
appType: AppId;
providerId: string;
@@ -64,7 +98,7 @@ export const providersApi = {
},
async update(
provider: Provider,
provider: ProviderUpdateInput,
appId: AppId,
originalId?: string,
): Promise<boolean> {
+6 -2
View File
@@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { providersApi, sessionsApi, settingsApi, type AppId } from "@/lib/api";
import type { DeleteSessionOptions } from "@/lib/api/sessions";
import type { SwitchResult } from "@/lib/api/providers";
import { toProviderUpdateInput, type SwitchResult } from "@/lib/api/providers";
import type { Provider, SessionMeta, Settings } from "@/types";
import { extractErrorMessage } from "@/utils/errorUtils";
import { generateUUID } from "@/utils/uuid";
@@ -168,7 +168,11 @@ export const useUpdateProviderMutation = (appId: AppId) => {
provider: Provider;
originalId?: string;
}) => {
await providersApi.update(provider, appId, originalId);
await providersApi.update(
toProviderUpdateInput(provider),
appId,
originalId,
);
return provider;
},
onSuccess: async (provider, variables) => {