refactor: remove api-types.ts compatibility layer

- Migrated all 29 files from api-types.ts to use reflector-api.d.ts directly
- Removed $SourceKind manual enum in favor of OpenAPI-generated types
- Fixed unrelated Spinner component TypeScript error in AuthWrapper.tsx
- All imports now use: import type { components } from "path/to/reflector-api"
- Deleted api-types.ts file completely
This commit is contained in:
2025-08-29 16:35:33 -06:00
parent 8c525e09e8
commit 7ddae5ddd5
35 changed files with 96 additions and 77 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -19,7 +19,7 @@ export default function AuthWrapper({
justifyContent="center"
h="calc(100vh - 80px)" // Account for header height
>
<Spinner size="xl" color="blue.500" thickness="4px" />
<Spinner size="xl" color="blue.500" />
</Flex>
);
}

View File

@@ -1,7 +1,10 @@
import React from "react";
import { Box, Stack, Link, Heading } from "@chakra-ui/react";
import NextLink from "next/link";
import { Room, SourceKind } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type Room = components["schemas"]["Room"];
type SourceKind = components["schemas"]["SourceKind"];
interface FilterSidebarProps {
rooms: Room[];

View File

@@ -18,7 +18,10 @@ import {
highlightMatches,
generateTextFragment,
} from "../../../lib/textHighlight";
import { SearchResult, SourceKind } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type SearchResult = components["schemas"]["SearchResult"];
type SourceKind = components["schemas"]["SourceKind"];
interface TranscriptCardsProps {
results: SearchResult[];

View File

@@ -20,12 +20,11 @@ import {
} from "nuqs";
import { LuX } from "react-icons/lu";
import useSessionUser from "../../lib/useSessionUser";
import {
Room,
SourceKind,
SearchResult,
$SourceKind,
} from "../../lib/api-types";
import type { components } from "../../reflector-api";
type Room = components["schemas"]["Room"];
type SourceKind = components["schemas"]["SourceKind"];
type SearchResult = components["schemas"]["SearchResult"];
import {
useRoomsList,
useTranscriptsSearch,
@@ -204,7 +203,7 @@ export default function TranscriptBrowser() {
const [urlSourceKind, setUrlSourceKind] = useQueryState(
"source",
parseAsStringLiteral($SourceKind.values).withOptions({
parseAsStringLiteral(["room", "live", "file"] as const).withOptions({
shallow: false,
}),
);

View File

@@ -12,7 +12,9 @@ import {
HStack,
} from "@chakra-ui/react";
import { LuLink } from "react-icons/lu";
import { Room } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type Room = components["schemas"]["Room"];
import { RoomActionsMenu } from "./RoomActionsMenu";
interface RoomCardsProps {

View File

@@ -1,5 +1,7 @@
import { Box, Heading, Text, VStack } from "@chakra-ui/react";
import { Room } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type Room = components["schemas"]["Room"];
import { RoomTable } from "./RoomTable";
import { RoomCards } from "./RoomCards";

View File

@@ -9,7 +9,9 @@ import {
Spinner,
} from "@chakra-ui/react";
import { LuLink } from "react-icons/lu";
import { Room } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type Room = components["schemas"]["Room"];
import { RoomActionsMenu } from "./RoomActionsMenu";
interface RoomTableProps {

View File

@@ -16,7 +16,7 @@ import {
} from "@chakra-ui/react";
import { useEffect, useState } from "react";
import useRoomList from "./useRoomList";
import { Room } from "../../lib/api-types";
import type { components } from "../../reflector-api";
import {
useRoomCreate,
useRoomUpdate,
@@ -27,6 +27,8 @@ import {
import { RoomList } from "./_components/RoomList";
import { PaginationPage } from "../browse/_components/Pagination";
type Room = components["schemas"]["Room"];
interface SelectOption {
label: string;
value: string;

View File

@@ -1,5 +1,7 @@
import { useRoomsList } from "../../lib/api-hooks";
import { Page_Room_ } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type Page_Room_ = components["schemas"]["Page_Room_"];
import { PaginationPage } from "../browse/_components/Pagination";
type RoomList = {

View File

@@ -6,7 +6,8 @@ import TopicPlayer from "./topicPlayer";
import useParticipants from "../../useParticipants";
import useTopicWithWords from "../../useTopicWithWords";
import ParticipantList from "./participantList";
import { GetTranscriptTopic } from "../../../../lib/api-types";
import type { components } from "../../../../reflector-api";
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
import { SelectedText, selectedTextIsTimeSlice } from "./types";
import { useTranscriptUpdate } from "../../../../lib/api-hooks";
import useTranscript from "../../useTranscript";

View File

@@ -1,7 +1,8 @@
import { faArrowTurnDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ChangeEvent, useEffect, useRef, useState } from "react";
import { Participant } from "../../../../lib/api-types";
import type { components } from "../../../../reflector-api";
type Participant = components["schemas"]["Participant"];
import {
useTranscriptSpeakerAssign,
useTranscriptSpeakerMerge,

View File

@@ -1,6 +1,7 @@
import useTopics from "../../useTopics";
import { Dispatch, SetStateAction, useEffect } from "react";
import { GetTranscriptTopic } from "../../../../lib/api-types";
import type { components } from "../../../../reflector-api";
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
import {
BoxProps,
Box,

View File

@@ -2,7 +2,9 @@ import { useEffect, useRef, useState } from "react";
import React from "react";
import Markdown from "react-markdown";
import "../../../styles/markdown.css";
import { GetTranscript, GetTranscriptTopic } from "../../../lib/api-types";
import type { components } from "../../../reflector-api";
type GetTranscript = components["schemas"]["GetTranscript"];
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
import { useTranscriptUpdate } from "../../../lib/api-hooks";
import {
Flex,

View File

@@ -1,6 +1,9 @@
import { CreateTranscript, GetTranscript } from "../../lib/api-types";
import type { components } from "../../reflector-api";
import { useTranscriptCreate } from "../../lib/api-hooks";
type CreateTranscript = components["schemas"]["CreateTranscript"];
type GetTranscript = components["schemas"]["GetTranscript"];
type UseCreateTranscript = {
transcript: GetTranscript | null;
loading: boolean;

View File

@@ -5,7 +5,9 @@ import RegionsPlugin from "wavesurfer.js/dist/plugins/regions.esm.js";
import { formatTime, formatTimeMs } from "../../lib/time";
import { Topic } from "./webSocketTypes";
import { AudioWaveform } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type AudioWaveform = components["schemas"]["AudioWaveform"];
import { waveSurferStyles } from "../../styles/recorder";
import { Box, Flex, IconButton } from "@chakra-ui/react";
import { LuPause, LuPlay } from "react-icons/lu";

View File

@@ -2,11 +2,10 @@ import { useEffect, useState } from "react";
import { featureEnabled } from "../../domainContext";
import { ShareMode, toShareMode } from "../../lib/shareMode";
import {
GetTranscript,
GetTranscriptTopic,
UpdateTranscript,
} from "../../lib/api-types";
import type { components } from "../../reflector-api";
type GetTranscript = components["schemas"]["GetTranscript"];
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
type UpdateTranscript = components["schemas"]["UpdateTranscript"];
import {
Box,
Flex,

View File

@@ -1,5 +1,7 @@
import { useState } from "react";
import { GetTranscript, GetTranscriptTopic } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type GetTranscript = components["schemas"]["GetTranscript"];
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
import { Button, BoxProps, Box } from "@chakra-ui/react";
type ShareCopyProps = {

View File

@@ -1,6 +1,9 @@
import { useState, useEffect, useMemo } from "react";
import { featureEnabled } from "../../domainContext";
import { GetTranscript, GetTranscriptTopic } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type GetTranscript = components["schemas"]["GetTranscript"];
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
import {
BoxProps,
Button,

View File

@@ -1,5 +1,7 @@
import { useState } from "react";
import { UpdateTranscript } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type UpdateTranscript = components["schemas"]["UpdateTranscript"];
import { useTranscriptUpdate } from "../../lib/api-hooks";
import { Heading, IconButton, Input, Flex, Spacer } from "@chakra-ui/react";
import { LuPen } from "react-icons/lu";

View File

@@ -1,4 +1,5 @@
import { Participant } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type Participant = components["schemas"]["Participant"];
import { useTranscriptParticipants } from "../../lib/api-hooks";
type ErrorParticipants = {

View File

@@ -1,5 +1,7 @@
// Wrapper for backward compatibility
import { SearchResult, SourceKind } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type SearchResult = components["schemas"]["SearchResult"];
type SourceKind = components["schemas"]["SourceKind"];
import { useTranscriptsSearch } from "../../lib/api-hooks";
import {
PaginationPage,

View File

@@ -1,6 +1,9 @@
import { GetTranscriptTopicWithWordsPerSpeaker } from "../../lib/api-types";
import type { components } from "../../reflector-api";
import { useTranscriptTopicsWithWordsPerSpeaker } from "../../lib/api-hooks";
type GetTranscriptTopicWithWordsPerSpeaker =
components["schemas"]["GetTranscriptTopicWithWordsPerSpeaker"];
type ErrorTopicWithWords = {
error: Error;
loading: false;

View File

@@ -1,5 +1,7 @@
import { useTranscriptTopics } from "../../lib/api-hooks";
import { GetTranscriptTopic } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
type TranscriptTopics = {
topics: GetTranscriptTopic[] | null;

View File

@@ -1,6 +1,8 @@
import { GetTranscript } from "../../lib/api-types";
import type { components } from "../../reflector-api";
import { useTranscriptGet } from "../../lib/api-hooks";
type GetTranscript = components["schemas"]["GetTranscript"];
type ErrorTranscript = {
error: Error;
loading: false;

View File

@@ -1,6 +1,8 @@
import { AudioWaveform } from "../../lib/api-types";
import type { components } from "../../reflector-api";
import { useTranscriptWaveform } from "../../lib/api-hooks";
type AudioWaveform = components["schemas"]["AudioWaveform"];
type AudioWaveFormResponse = {
waveform: AudioWaveform | null;
loading: boolean;

View File

@@ -2,7 +2,8 @@ import { useEffect, useState } from "react";
import Peer from "simple-peer";
import { useError } from "../../(errors)/errorContext";
import { useTranscriptWebRTC } from "../../lib/api-hooks";
import { RtcOffer } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type RtcOffer = components["schemas"]["RtcOffer"];
const useWebRTC = (
stream: MediaStream | null,

View File

@@ -2,7 +2,10 @@ import { useContext, useEffect, useState } from "react";
import { Topic, FinalSummary, Status } from "./webSocketTypes";
import { useError } from "../../(errors)/errorContext";
import { DomainContext } from "../../domainContext";
import { AudioWaveform, GetTranscriptSegmentTopic } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type AudioWaveform = components["schemas"]["AudioWaveform"];
type GetTranscriptSegmentTopic =
components["schemas"]["GetTranscriptSegmentTopic"];
import { useQueryClient } from "@tanstack/react-query";
import { $api } from "../../lib/apiClient";

View File

@@ -1,4 +1,6 @@
import { GetTranscriptTopic } from "../../lib/api-types";
import type { components } from "../../reflector-api";
type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
export type Topic = GetTranscriptTopic;

View File

@@ -24,7 +24,9 @@ import { notFound } from "next/navigation";
import useSessionStatus from "../lib/useSessionStatus";
import { useRecordingConsent } from "../recordingConsentContext";
import { useMeetingAudioConsent } from "../lib/api-hooks";
import { Meeting } from "../lib/api-types";
import type { components } from "../reflector-api";
type Meeting = components["schemas"]["Meeting"];
import { FaBars } from "react-icons/fa6";
export type RoomDetails = {

View File

@@ -1,7 +1,9 @@
import { useEffect, useState } from "react";
import { useError } from "../(errors)/errorContext";
import { Meeting } from "../lib/api-types";
import type { components } from "../reflector-api";
import { shouldShowError } from "../lib/errorUtils";
type Meeting = components["schemas"]["Meeting"];
import { useRoomsCreateMeeting } from "../lib/api-hooks";
import { notFound } from "next/navigation";

View File

@@ -4,13 +4,10 @@ import { useEffect } from "react";
import { configureApiAuth } from "./apiClient";
import useSessionAccessToken from "./useSessionAccessToken";
// Note: Base URL is now configured directly in apiClient.tsx
export function ApiAuthProvider({ children }: { children: React.ReactNode }) {
const { accessToken } = useSessionAccessToken();
useEffect(() => {
// Configure authentication
configureApiAuth(accessToken);
}, [accessToken]);

View File

@@ -1,27 +0,0 @@
// Re-export types from generated OpenAPI schema for backward compatibility
import type { components } from "../reflector-api";
// Export types with their original names
export type Room = components["schemas"]["Room"];
export type Meeting = components["schemas"]["Meeting"];
export type SourceKind = components["schemas"]["SourceKind"];
export type SearchResult = components["schemas"]["SearchResult"];
export type GetTranscript = components["schemas"]["GetTranscript"];
export type GetTranscriptTopic = components["schemas"]["GetTranscriptTopic"];
export type UpdateTranscript = components["schemas"]["UpdateTranscript"];
export type AudioWaveform = components["schemas"]["AudioWaveform"];
export type Participant = components["schemas"]["Participant"];
export type CreateTranscript = components["schemas"]["CreateTranscript"];
export type RtcOffer = components["schemas"]["RtcOffer"];
export type GetTranscriptSegmentTopic =
components["schemas"]["GetTranscriptSegmentTopic"];
export type Page_Room_ = components["schemas"]["Page_Room_"];
export type GetTranscriptTopicWithWordsPerSpeaker =
components["schemas"]["GetTranscriptTopicWithWordsPerSpeaker"];
export type GetTranscriptMinimal =
components["schemas"]["GetTranscriptMinimal"];
// Export any enums or constants that were in the old API
export const $SourceKind = {
values: ["room", "live", "file"] as const,
} as const;

View File

@@ -16,23 +16,21 @@ export const client = createClient<paths>({
baseUrl: "http://127.0.0.1:1250",
});
// Create the React Query client wrapper
export const $api = createFetchClient<paths>(client);
// Store the current auth token and ready state
let currentAuthToken: string | null | undefined = null;
let authConfigured = false;
// Export function to check if auth is ready
export const isAuthConfigured = () => authConfigured;
// Set up authentication middleware once
client.use({
onRequest({ request }) {
if (currentAuthToken) {
request.headers.set("Authorization", `Bearer ${currentAuthToken}`);
}
// Only set Content-Type if not already set (FormData will set its own boundary)
// XXX Only set Content-Type if not already set (FormData will set its own boundary)
// This is a work around for uploading file, we're passing a formdata
// but the content type was still application/json
if (
!request.headers.has("Content-Type") &&
!(request.body instanceof FormData)
@@ -43,13 +41,11 @@ client.use({
},
});
// Configure authentication by updating the token
export const configureApiAuth = (token: string | null | undefined) => {
currentAuthToken = token;
authConfigured = true;
};
// Export typed hooks for convenience
export const useApiQuery = $api.useQuery;
export const useApiMutation = $api.useMutation;
export const useApiSuspenseQuery = $api.useSuspenseQuery;