This commit is contained in:
2026-07-10 16:41:22 +09:00
parent bbda38a013
commit 50d75fcfcd
47 changed files with 6309 additions and 350 deletions
+118 -7
View File
@@ -17,6 +17,46 @@ export interface FileUploadResponse {
files: UploadedFileResult[];
}
export interface ChunkSessionCreateResponse {
status: string;
project_id: string;
upload_session_id: string;
original_filename: string;
file_size_bytes: number;
chunk_size_bytes: number;
total_chunks: number;
completed_chunks: number;
}
export interface ChunkUploadResponse {
status: string;
upload_session_id: string;
chunk_index: number;
completed_chunks: number;
total_chunks: number;
chunk_hash: string;
}
export interface UploadStatusResponse {
status: string;
upload_session_id: string;
upload_status: string;
original_filename: string;
file_size_bytes: number;
chunk_size_bytes: number;
total_chunks: number;
completed_chunks: number;
completed_chunk_indexes: number[];
}
async function readJsonOrThrow<T>(response: Response): Promise<T> {
const payload = (await response.json()) as T & { message?: string };
if (!response.ok) {
throw new Error(payload.message ?? `HTTP ${response.status}`);
}
return payload;
}
export async function uploadProjectFiles(
projectId: string,
files: readonly File[],
@@ -33,14 +73,85 @@ export async function uploadProjectFiles(
body: formData,
signal: controller.signal,
});
const payload = (await response.json()) as Partial<FileUploadResponse> & {
message?: string;
};
if (!response.ok) {
throw new Error(payload.message ?? `HTTP ${response.status}`);
}
return payload as FileUploadResponse;
return await readJsonOrThrow<FileUploadResponse>(response);
} finally {
window.clearTimeout(timeoutId);
}
}
export async function createUploadSession(
projectId: string,
file: File,
chunkSizeBytes: number,
): Promise<ChunkSessionCreateResponse> {
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/upload-sessions`, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
original_filename: file.name,
size_bytes: file.size,
chunk_size_bytes: chunkSizeBytes,
}),
});
return await readJsonOrThrow<ChunkSessionCreateResponse>(response);
}
export async function uploadFileChunk(
projectId: string,
sessionId: string,
chunkIndex: number,
chunk: Blob,
): Promise<ChunkUploadResponse> {
const formData = new FormData();
formData.append("session_id", sessionId);
formData.append("chunk_index", String(chunkIndex));
formData.append("chunk_data", chunk, `${sessionId}-${chunkIndex}.chunk`);
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/chunks`, {
method: "POST",
credentials: "include",
body: formData,
});
return await readJsonOrThrow<ChunkUploadResponse>(response);
}
export async function finalizeUploadSession(
projectId: string,
sessionId: string,
totalChunks: number,
): Promise<FileUploadResponse> {
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/finalize`, {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ session_id: sessionId, total_chunks: totalChunks }),
});
return await readJsonOrThrow<FileUploadResponse>(response);
}
export async function fetchUploadStatus(
projectId: string,
sessionId: string,
): Promise<UploadStatusResponse> {
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/upload-status/${sessionId}`, {
method: "GET",
credentials: "include",
});
return await readJsonOrThrow<UploadStatusResponse>(response);
}
export interface WF1AnalysisStatus {
project_id: string;
status: "pending" | "in_progress" | "completed" | "failed";
model_count: number;
error?: string;
}
export async function checkWF1AnalysisStatus(projectId: string): Promise<WF1AnalysisStatus> {
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/surface/status`, {
method: "GET",
credentials: "include",
});
return await readJsonOrThrow<WF1AnalysisStatus>(response);
}