submission api client
This commit is contained in:
@@ -5,10 +5,23 @@ import type {
|
||||
QuestionDetail,
|
||||
QuestionListResponse,
|
||||
Stats,
|
||||
SubmissionRequest,
|
||||
SubmissionResponse,
|
||||
} from "@/types";
|
||||
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000";
|
||||
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
public statusText: string,
|
||||
public detail?: string
|
||||
) {
|
||||
super(detail || `API error: ${status} ${statusText}`);
|
||||
this.name = "ApiError";
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchApi<T>(
|
||||
endpoint: string,
|
||||
options?: RequestInit
|
||||
@@ -23,7 +36,14 @@ async function fetchApi<T>(
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API error: ${response.status} ${response.statusText}`);
|
||||
let detail: string | undefined;
|
||||
try {
|
||||
const errorBody = await response.json();
|
||||
detail = errorBody.detail;
|
||||
} catch {
|
||||
// Ignore JSON parse errors
|
||||
}
|
||||
throw new ApiError(response.status, response.statusText, detail);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
@@ -77,3 +97,13 @@ export async function getPattern(slug: string): Promise<Pattern> {
|
||||
export async function getStats(): Promise<Stats> {
|
||||
return fetchApi<Stats>("/api/stats");
|
||||
}
|
||||
|
||||
export async function submitSolution(
|
||||
slug: string,
|
||||
submission: SubmissionRequest
|
||||
): Promise<SubmissionResponse> {
|
||||
return fetchApi<SubmissionResponse>(`/api/questions/${slug}/submit`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(submission),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -61,6 +61,17 @@ export interface Solution {
|
||||
explanation: string | null;
|
||||
}
|
||||
|
||||
export interface VisibleTestCase {
|
||||
id: number;
|
||||
input: Record<string, unknown>;
|
||||
expected: unknown;
|
||||
}
|
||||
|
||||
export interface HiddenTestInput {
|
||||
id: number;
|
||||
input: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface QuestionDetail extends QuestionListItem {
|
||||
description: string;
|
||||
constraints: string | null;
|
||||
@@ -69,6 +80,9 @@ export interface QuestionDetail extends QuestionListItem {
|
||||
output: string;
|
||||
explanation?: string;
|
||||
}> | null;
|
||||
function_signature: string | null;
|
||||
visible_test_cases: VisibleTestCase[] | null;
|
||||
hidden_test_inputs: HiddenTestInput[] | null;
|
||||
explanation: Explanation | null;
|
||||
solutions: Solution[];
|
||||
updated_at: string;
|
||||
@@ -114,3 +128,30 @@ export interface Stats {
|
||||
by_category: CategoryCount[];
|
||||
by_pattern: PatternCount[];
|
||||
}
|
||||
|
||||
export interface HiddenTestOutput {
|
||||
test_id: number;
|
||||
output: unknown;
|
||||
}
|
||||
|
||||
export interface SubmissionRequest {
|
||||
code: string;
|
||||
hidden_outputs: HiddenTestOutput[];
|
||||
}
|
||||
|
||||
export interface TestResult {
|
||||
test_id: number;
|
||||
passed: boolean;
|
||||
input?: Record<string, unknown>;
|
||||
expected?: unknown;
|
||||
actual: unknown;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface SubmissionResponse {
|
||||
passed: boolean;
|
||||
visible_results: TestResult[];
|
||||
hidden_results: TestResult[];
|
||||
total_passed: number;
|
||||
total_tests: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user