refactor(api): 收口 server/client 数据解析层,消除 aiGenerationClient 的 as T 断言
This commit is contained in:
@@ -1,12 +1,18 @@
|
||||
import {
|
||||
buildApiUrl,
|
||||
buildAuthHeaders,
|
||||
isRecord,
|
||||
readJsonResponse,
|
||||
serverRequest,
|
||||
throwResponseError,
|
||||
} from "./serverConnection";
|
||||
import { isOptionalApiRouteMissing } from "./apiErrorUtils";
|
||||
import {
|
||||
parseAiTaskStatus,
|
||||
parseAiTaskStatusList,
|
||||
parseImageTaskCreateResponse,
|
||||
parseSseTaskFrame,
|
||||
parseTaskCreateResponse,
|
||||
} from "./dtoParsers";
|
||||
import type { WebGenerationPreviewTask } from "../types";
|
||||
|
||||
export interface ImageGenInput {
|
||||
@@ -190,13 +196,6 @@ function parseContentDispositionFilename(value: string | null): string | undefin
|
||||
return plainMatch?.[1]?.trim() || undefined;
|
||||
}
|
||||
|
||||
function extractTaskList(payload: unknown): AiTaskStatus[] {
|
||||
if (Array.isArray(payload)) return payload as AiTaskStatus[];
|
||||
if (!isRecord(payload)) return [];
|
||||
const rows = payload.tasks ?? payload.items;
|
||||
return Array.isArray(rows) ? (rows as AiTaskStatus[]) : [];
|
||||
}
|
||||
|
||||
function getStoredSessionRole(): string {
|
||||
try {
|
||||
if (typeof window === "undefined") return "";
|
||||
@@ -251,67 +250,73 @@ export const aiGenerationClient = {
|
||||
projectId: input.projectId,
|
||||
conversationId: input.conversationId,
|
||||
});
|
||||
const payload = await serverRequest<ImageTaskCreateResponse>("ai/image", {
|
||||
const payload = await serverRequest<unknown>("ai/image", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Image generation request failed",
|
||||
});
|
||||
if (payload.providerDebug) {
|
||||
emitImageRouteDebug("[ai/image-provider-debug]", payload.providerDebug as Record<string, unknown>);
|
||||
const parsed = parseImageTaskCreateResponse(payload);
|
||||
if (parsed.providerDebug) {
|
||||
emitImageRouteDebug("[ai/image-provider-debug]", parsed.providerDebug as Record<string, unknown>);
|
||||
}
|
||||
return payload;
|
||||
return parsed;
|
||||
},
|
||||
|
||||
async createVideoTask(input: VideoGenInput): Promise<{ taskId: string }> {
|
||||
return serverRequest<{ taskId: string }>("ai/video", {
|
||||
const payload = await serverRequest<unknown>("ai/video", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Video generation request failed",
|
||||
});
|
||||
return parseTaskCreateResponse(payload);
|
||||
},
|
||||
|
||||
async createVideoSuperResolveTask(input: VideoSuperResolveInput): Promise<{ taskId: string }> {
|
||||
return serverRequest<{ taskId: string }>("ai/video/super-resolve", {
|
||||
const payload = await serverRequest<unknown>("ai/video/super-resolve", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Video super-resolution request failed",
|
||||
});
|
||||
return parseTaskCreateResponse(payload);
|
||||
},
|
||||
|
||||
async createEraseSubtitlesTask(input: EraseSubtitlesInput): Promise<{ taskId: string }> {
|
||||
return serverRequest<{ taskId: string }>("ai/video/erase-subtitles", {
|
||||
const payload = await serverRequest<unknown>("ai/video/erase-subtitles", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Subtitle removal request failed",
|
||||
});
|
||||
return parseTaskCreateResponse(payload);
|
||||
},
|
||||
|
||||
async createImageSuperResolveTask(input: ImageSuperResolveInput): Promise<{ taskId: string }> {
|
||||
return serverRequest<{ taskId: string }>("ai/image/super-resolve", {
|
||||
const payload = await serverRequest<unknown>("ai/image/super-resolve", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Image super-resolution request failed",
|
||||
});
|
||||
return parseTaskCreateResponse(payload);
|
||||
},
|
||||
|
||||
async createImageEditTask(input: ImageEditInput): Promise<{ taskId: string }> {
|
||||
return serverRequest<{ taskId: string }>("ai/image/edit", {
|
||||
const payload = await serverRequest<unknown>("ai/image/edit", {
|
||||
method: "POST",
|
||||
body: input,
|
||||
timeoutMs: TASK_SUBMIT_TIMEOUT_MS,
|
||||
maxRetries: NON_RETRYING_REQUEST.maxRetries,
|
||||
fallbackMessage: "Image edit request failed",
|
||||
});
|
||||
return parseTaskCreateResponse(payload);
|
||||
},
|
||||
|
||||
async cancelTask(taskId: string): Promise<void> {
|
||||
@@ -328,10 +333,11 @@ export const aiGenerationClient = {
|
||||
},
|
||||
|
||||
async getTaskStatus(taskId: string): Promise<AiTaskStatus> {
|
||||
return serverRequest<AiTaskStatus>(`ai/tasks/${taskId}`, {
|
||||
const payload = await serverRequest<unknown>(`ai/tasks/${taskId}`, {
|
||||
timeoutMs: TASK_STATUS_TIMEOUT_MS,
|
||||
fallbackMessage: "Task status request failed",
|
||||
});
|
||||
return parseAiTaskStatus(payload);
|
||||
},
|
||||
|
||||
async downloadTaskResult(taskId: string): Promise<{ blob: Blob; filename?: string; contentType?: string }> {
|
||||
@@ -361,7 +367,7 @@ export const aiGenerationClient = {
|
||||
const payload = await serverRequest<unknown>(`ai/tasks${search.toString() ? `?${search}` : ""}`, {
|
||||
fallbackMessage: "Task history request failed",
|
||||
});
|
||||
return extractTaskList(payload).map(toPreviewTask);
|
||||
return parseAiTaskStatusList(payload).map(toPreviewTask);
|
||||
} catch (error) {
|
||||
if (isOptionalApiRouteMissing(error)) {
|
||||
taskHistoryRouteMissing = true;
|
||||
@@ -451,7 +457,7 @@ export const aiGenerationClient = {
|
||||
if (!line.startsWith("data: ")) continue;
|
||||
try {
|
||||
const data = JSON.parse(line.slice(6));
|
||||
onUpdate(data);
|
||||
onUpdate(parseSseTaskFrame(data));
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user