Download src/lib/api/normalizers.ts from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 7.5 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/api/normalizers.ts
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/lib/api/normalizers.ts
-
curl -L -o normalizers.ts https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/lib/api/normalizers.ts
7.5 kB
| import type { | |
| ApiDocument, | |
| DocumentStatus, | |
| ExamModeOutput, | |
| FlashcardResponseItem, | |
| FlashcardsPayload, | |
| NotesOutput, | |
| PreviousPaperAnalysisResponse, | |
| QuizQuestionResponse, | |
| QuizQuestionsPayload, | |
| StudyPathResponse, | |
| VideoPlanV2Response, | |
| VideoRenderJob, | |
| VideoRenderJobStatus, | |
| VideoScenePlanResponse, | |
| } from "@/lib/api/types"; | |
| type UnknownRecord = Record<string, unknown>; | |
| function isRecord(value: unknown): value is UnknownRecord { | |
| return Boolean(value && typeof value === "object" && !Array.isArray(value)); | |
| } | |
| function readString(value: unknown, fallback = "") { | |
| return typeof value === "string" && value.trim() ? value : fallback; | |
| } | |
| function readStringArray(value: unknown): string[] { | |
| if (!Array.isArray(value)) return []; | |
| return value.map((item) => String(item)).filter((item) => item.trim().length > 0); | |
| } | |
| export function normalizeDocument(value: unknown): ApiDocument { | |
| const record = isRecord(value) ? value : {}; | |
| const now = new Date().toISOString(); | |
| return { | |
| id: readString(record.id, `doc-local-${Date.now()}`), | |
| user_id: readString(record.user_id, "demo-user-student"), | |
| title: readString(record.title, "Study source"), | |
| file_name: readString(record.file_name, "source.pdf"), | |
| file_type: readString(record.file_type, "PDF"), | |
| subject: typeof record.subject === "string" ? record.subject : null, | |
| chapter: typeof record.chapter === "string" ? record.chapter : null, | |
| syllabus: typeof record.syllabus === "string" ? record.syllabus : null, | |
| status: normalizeDocumentStatus(record.status), | |
| // extracted_text removed — raw OCR text is not returned by the API | |
| extracted_text_length: typeof record.extracted_text_length === "number" ? record.extracted_text_length : null, | |
| chunk_count: typeof record.chunk_count === "number" ? record.chunk_count : 0, | |
| created_at: readString(record.created_at, now), | |
| }; | |
| } | |
| export function normalizeDocumentStatus(value: unknown): DocumentStatus { | |
| if (value === "ready" || value === "processing" || value === "failed" || value === "uploaded") { | |
| return value; | |
| } | |
| return "ready"; | |
| } | |
| export function normalizeNotes(value: unknown): NotesOutput { | |
| const record = isRecord(value) ? value : {}; | |
| // Backend returns exam_keywords; exam_focus is a frontend-side alias | |
| const examKeywords = readStringArray(record.exam_keywords); | |
| return { | |
| title: readString(record.title, "Smart Notes"), | |
| summary: typeof record.summary === "string" ? record.summary : undefined, | |
| student_level_summary: typeof record.student_level_summary === "string" ? record.student_level_summary : undefined, | |
| key_points: readStringArray(record.key_points).length ? readStringArray(record.key_points) : ["Review the main ideas first."], | |
| important_keywords: readStringArray(record.important_keywords), | |
| important_definitions: readStringArray(record.important_definitions), | |
| formulas: readStringArray(record.formulas), | |
| diagrams_to_practice: readStringArray(record.diagrams_to_practice), | |
| memory_tricks: readStringArray(record.memory_tricks), | |
| exam_keywords: examKeywords, | |
| exam_focus: readStringArray(record.exam_focus).length ? readStringArray(record.exam_focus) : examKeywords, | |
| possible_exam_questions: readStringArray(record.possible_exam_questions), | |
| last_minute_revision: readStringArray(record.last_minute_revision), | |
| quick_check: readStringArray(record.quick_check), | |
| source_summary: typeof record.source_summary === "string" ? record.source_summary : undefined, | |
| scoring_keywords: readStringArray(record.scoring_keywords), | |
| common_mistakes: readStringArray(record.common_mistakes), | |
| ten_minute_revision: readStringArray(record.ten_minute_revision), | |
| next_study_action: typeof record.next_study_action === "string" ? record.next_study_action : undefined, | |
| caution_note: typeof record.caution_note === "string" ? record.caution_note : undefined, | |
| }; | |
| } | |
| export function normalizeQuiz(value: unknown): QuizQuestionResponse[] { | |
| const payload: QuizQuestionsPayload | unknown = value; | |
| if (Array.isArray(payload)) return payload.filter(isRecord).map(normalizeQuizQuestion); | |
| if (isRecord(payload) && Array.isArray(payload.questions)) { | |
| return payload.questions.filter(isRecord).map(normalizeQuizQuestion); | |
| } | |
| return []; | |
| } | |
| function normalizeQuizQuestion(value: UnknownRecord): QuizQuestionResponse { | |
| return { | |
| question: readString(value.question, "Practice question"), | |
| type: readString(value.type, "MCQ"), | |
| options: readStringArray(value.options), | |
| answer: readString(value.answer, "Review the explanation."), | |
| explanation: typeof value.explanation === "string" ? value.explanation : undefined, | |
| difficulty: readString(value.difficulty, "Practice"), | |
| topic: typeof value.topic === "string" ? value.topic : undefined, | |
| why_this_matters: typeof value.why_this_matters === "string" ? value.why_this_matters : undefined, | |
| common_trap: typeof value.common_trap === "string" ? value.common_trap : undefined, | |
| }; | |
| } | |
| export function normalizeFlashcards(value: unknown): FlashcardResponseItem[] { | |
| const payload: FlashcardsPayload | unknown = value; | |
| if (Array.isArray(payload)) return payload.filter(isRecord).map(normalizeFlashcard); | |
| if (isRecord(payload) && Array.isArray(payload.cards)) { | |
| return payload.cards.filter(isRecord).map(normalizeFlashcard); | |
| } | |
| return []; | |
| } | |
| function normalizeFlashcard(value: UnknownRecord): FlashcardResponseItem { | |
| return { | |
| front: readString(value.front, "Key idea"), | |
| back: readString(value.back, "Short explanation"), | |
| hint: typeof value.hint === "string" ? value.hint : undefined, | |
| tag: typeof value.tag === "string" ? value.tag : undefined, | |
| topic: typeof value.topic === "string" ? value.topic : undefined, | |
| memory_hook: typeof value.memory_hook === "string" ? value.memory_hook : undefined, | |
| exam_use: typeof value.exam_use === "string" ? value.exam_use : undefined, | |
| }; | |
| } | |
| export function normalizePYQAnalysis(value: unknown): PreviousPaperAnalysisResponse | null { | |
| return isRecord(value) && Array.isArray(value.repeated_topics) | |
| ? (value as PreviousPaperAnalysisResponse) | |
| : null; | |
| } | |
| export function normalizeStudyPlan(value: unknown): StudyPathResponse | null { | |
| return isRecord(value) && Array.isArray(value.blocks) ? (value as StudyPathResponse) : null; | |
| } | |
| export function normalizeExamAnswer(value: unknown): ExamModeOutput | null { | |
| return isRecord(value) ? (value as ExamModeOutput) : null; | |
| } | |
| export function normalizeVideoPlan(value: unknown): VideoScenePlanResponse | VideoPlanV2Response | null { | |
| if (!isRecord(value)) return null; | |
| if (Array.isArray(value.scenes) || Array.isArray(value.sections)) { | |
| return value as VideoScenePlanResponse | VideoPlanV2Response; | |
| } | |
| return null; | |
| } | |
| export function normalizeRenderJob(value: unknown): VideoRenderJob | null { | |
| return isRecord(value) && typeof value.id === "string" ? (value as VideoRenderJob) : null; | |
| } | |
| export function normalizeRenderStatus(value: unknown): VideoRenderJobStatus { | |
| if ( | |
| value === "ready" || | |
| value === "failed" || | |
| value === "queued" || | |
| value === "running" || | |
| value === "planning" || | |
| value === "script_ready" || | |
| value === "audio_generating" || | |
| value === "visuals_generating" || | |
| value === "rendering" || | |
| value === "uploading" || | |
| value === "complete" | |
| ) { | |
| return value; | |
| } | |
| if (value === "completed") return "complete"; | |
| if (value === "processing") return "running"; | |
| return "queued"; | |
| } | |