feat(auth-files): enhance error handling for invalid JSON and refactor file upload logic

This commit is contained in:
Supra4E8C
2026-03-07 16:06:23 +08:00
parent ccf90f88dd
commit cb8208e0f7
3 changed files with 82 additions and 29 deletions
+49 -2
View File
@@ -9,12 +9,39 @@ import type { OAuthModelAliasEntry } from '@/types';
type StatusError = { status?: number };
type AuthFileStatusResponse = { status: string; disabled: boolean };
export const AUTH_FILE_INVALID_JSON_OBJECT_ERROR = 'AUTH_FILE_INVALID_JSON_OBJECT';
const getStatusCode = (err: unknown): number | undefined => {
if (!err || typeof err !== 'object') return undefined;
if ('status' in err) return (err as StatusError).status;
return undefined;
};
const parseAuthFileJsonObject = (rawText: string): Record<string, unknown> => {
const trimmed = rawText.trim();
let parsed: unknown;
try {
parsed = JSON.parse(trimmed) as unknown;
} catch {
throw new Error(AUTH_FILE_INVALID_JSON_OBJECT_ERROR);
}
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error(AUTH_FILE_INVALID_JSON_OBJECT_ERROR);
}
return { ...(parsed as Record<string, unknown>) };
};
const saveAuthFileText = async (name: string, text: string) => {
const file = new File([text], name, { type: 'application/json' });
await authFilesApi.upload(file);
};
export const isAuthFileInvalidJsonObjectError = (err: unknown): boolean =>
err instanceof Error && err.message === AUTH_FILE_INVALID_JSON_OBJECT_ERROR;
const normalizeOauthExcludedModels = (payload: unknown): Record<string, string[]> => {
if (!payload || typeof payload !== 'object') return {};
@@ -105,8 +132,18 @@ const OAUTH_MODEL_ALIAS_ENDPOINT = '/oauth-model-alias';
export const authFilesApi = {
list: () => apiClient.get<AuthFilesResponse>('/auth-files'),
setStatus: (name: string, disabled: boolean) =>
apiClient.patch<AuthFileStatusResponse>('/auth-files/status', { name, disabled }),
async setStatus(name: string, disabled: boolean): Promise<AuthFileStatusResponse> {
const json = await authFilesApi.downloadJsonObject(name);
if (disabled) {
json.disabled = true;
} else {
delete json.disabled;
}
await authFilesApi.saveJsonObject(name, json);
return { status: disabled ? 'disabled' : 'enabled', disabled };
},
upload: (file: File) => {
const formData = new FormData();
@@ -126,6 +163,16 @@ export const authFilesApi = {
return blob.text();
},
async downloadJsonObject(name: string): Promise<Record<string, unknown>> {
const rawText = await authFilesApi.downloadText(name);
return parseAuthFileJsonObject(rawText);
},
saveText: (name: string, text: string) => saveAuthFileText(name, text),
saveJsonObject: (name: string, json: Record<string, unknown>) =>
saveAuthFileText(name, JSON.stringify(json)),
// OAuth 排除模型
async getOauthExcludedModels(): Promise<Record<string, string[]>> {
const data = await apiClient.get('/oauth-excluded-models');