Merge pull request #366 from Monadical-SAS/separate-ui-for-file-upload

UI for file upload
This commit is contained in:
2024-07-05 19:05:28 +02:00
committed by GitHub
69 changed files with 2897 additions and 2342 deletions

View File

@@ -4,9 +4,9 @@ Reflector Audio Management and Analysis is a cutting-edge web application under
The project architecture consists of three primary components:
* **Front-End**: NextJS React project hosted on Vercel, located in `www/`.
* **Back-End**: Python server that offers an API and data persistence, found in `server/`.
* **GPU implementation**: Providing services such as speech-to-text transcription, topic generation, automated summaries, and translations.
- **Front-End**: NextJS React project hosted on Vercel, located in `www/`.
- **Back-End**: Python server that offers an API and data persistence, found in `server/`.
- **GPU implementation**: Providing services such as speech-to-text transcription, topic generation, automated summaries, and translations.
It also uses https://github.com/fief-dev for authentication, and Vercel for deployment and configuration of the front-end.
@@ -41,26 +41,28 @@ It also uses https://github.com/fief-dev for authentication, and Vercel for depl
All new contributions should be made in a separate branch. Before any code is merged into `main`, it requires a code review.
### How to Install Blackhole (Mac Only)
To record both your voice and the meeting you're taking part in, you need :
- For an in-person meeting, make sure your microphone is in range of all participants.
- If using several miscrophones, make sure to merge the audio feeds into one with an external tool.
- For an online meeting, if you do not use headphones, your microphone should be able to pick up both your voice and the audio feed of the meeting.
- If you want to use headphones, you need to merge the audio feeds with an external tool.
This is an external tool for merging the audio feeds as explained in the previous section of this document.
Note: We currently do not have instructions for Windows users.
* Install [Blackhole](https://github.com/ExistentialAudio/BlackHole)-2ch (2 ch is enough) by 1 of 2 options listed.
* Setup ["Aggregate device"](https://github.com/ExistentialAudio/BlackHole/wiki/Aggregate-Device) to route web audio and local microphone input.
* Setup [Multi-Output device](https://github.com/ExistentialAudio/BlackHole/wiki/Multi-Output-Device)
* Then goto ```System Preferences -> Sound``` and choose the devices created from the Output and Input tabs.
* The input from your local microphone, the browser run meeting should be aggregated into one virtual stream to listen to and the output should be fed back to your specified output devices if everything is configured properly.
- Install [Blackhole](https://github.com/ExistentialAudio/BlackHole)-2ch (2 ch is enough) by 1 of 2 options listed.
- Setup ["Aggregate device"](https://github.com/ExistentialAudio/BlackHole/wiki/Aggregate-Device) to route web audio and local microphone input.
- Setup [Multi-Output device](https://github.com/ExistentialAudio/BlackHole/wiki/Multi-Output-Device)
- Then goto `System Preferences -> Sound` and choose the devices created from the Output and Input tabs.
- The input from your local microphone, the browser run meeting should be aggregated into one virtual stream to listen to and the output should be fed back to your specified output devices if everything is configured properly.
Permissions:
You may have to add permission for browser's microphone access to record audio in
```System Preferences -> Privacy & Security -> Microphone```
```System Preferences -> Privacy & Security -> Accessibility```. You will be prompted to provide these when you try to connect.
`System Preferences -> Privacy & Security -> Microphone`
`System Preferences -> Privacy & Security -> Accessibility`. You will be prompted to provide these when you try to connect.
## Front-End
@@ -96,8 +98,6 @@ To generate the TypeScript files from the openapi.json file, make sure the pytho
yarn openapi
```
You may need to run `yarn global add @openapitools/openapi-generator-cli` first. You also need a Java runtime installed on your machine.
## Back-End
Start with `cd server`.
@@ -153,11 +153,13 @@ docker compose up -d redis
**Option 2**
Install:
- [Git for Windows](https://gitforwindows.org/)
- [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install)
- Install your preferred Linux distribution via the Microsoft Store (e.g., Ubuntu).
- Install your preferred Linux distribution via the Microsoft Store (e.g., Ubuntu).
Open your Linux distribution and update the package list:
```bash
sudo apt update
sudo apt install redis-server
@@ -198,7 +200,6 @@ docker-compose up server
- Ensure the API server is activated in GPT4all
- Run with: `LLM_BACKEND=openai LLM_URL=http://localhost:4891/v1/completions LLM_OPENAI_MODEL="GPT4All Falcon" python -m reflector.app`
### Using local files
```
@@ -207,5 +208,4 @@ poetry run python -m reflector.tools.process path/to/audio.wav
## AI Models
*(Documentation for this section is pending.)*
_(Documentation for this section is pending.)_

View File

@@ -37,7 +37,7 @@ export default function TranscriptCorrect({
const markAsDone = () => {
if (transcript.response && !transcript.response.reviewed) {
api
?.v1TranscriptUpdate(transcriptId, { reviewed: true })
?.v1TranscriptUpdate({ transcriptId, requestBody: { reviewed: true } })
.then(() => {
router.push(`/transcripts/${transcriptId}`);
})

View File

@@ -123,10 +123,13 @@ const ParticipantList = ({
setLoading(true);
try {
await api?.v1TranscriptAssignSpeaker(transcriptId, {
participant: participant.id,
timestamp_from: selectedText.start,
timestamp_to: selectedText.end,
await api?.v1TranscriptAssignSpeaker({
transcriptId,
requestBody: {
participant: participant.id,
timestamp_from: selectedText.start,
timestamp_to: selectedText.end,
},
});
onSuccess();
} catch (error) {
@@ -142,9 +145,12 @@ const ParticipantList = ({
setLoading(true);
if (participantTo.speaker) {
try {
await api?.v1TranscriptMergeSpeaker(transcriptId, {
speaker_from: speakerFrom,
speaker_to: participantTo.speaker,
await api?.v1TranscriptMergeSpeaker({
transcriptId,
requestBody: {
speaker_from: speakerFrom,
speaker_to: participantTo.speaker,
},
});
onSuccess();
} catch (error) {
@@ -153,11 +159,11 @@ const ParticipantList = ({
}
} else {
try {
await api?.v1TranscriptUpdateParticipant(
await api?.v1TranscriptUpdateParticipant({
transcriptId,
participantTo.id,
{ speaker: speakerFrom },
);
participantId: participantTo.id,
requestBody: { speaker: speakerFrom },
});
onSuccess();
} catch (error) {
setError(error, "There was an error merging (update)");
@@ -183,8 +189,12 @@ const ParticipantList = ({
if (participant && participant.name !== participantInput) {
setLoading(true);
api
?.v1TranscriptUpdateParticipant(transcriptId, participant.id, {
name: participantInput,
?.v1TranscriptUpdateParticipant({
transcriptId,
participantId: participant.id,
requestBody: {
name: participantInput,
},
})
.then(() => {
participants.refetch();
@@ -202,9 +212,12 @@ const ParticipantList = ({
) {
setLoading(true);
api
?.v1TranscriptAddParticipant(transcriptId, {
name: participantInput,
speaker: selectedText,
?.v1TranscriptAddParticipant({
transcriptId,
requestBody: {
name: participantInput,
speaker: selectedText,
},
})
.then(() => {
participants.refetch();
@@ -222,12 +235,12 @@ const ParticipantList = ({
) {
setLoading(true);
try {
const participant = await api?.v1TranscriptAddParticipant(
const participant = await api?.v1TranscriptAddParticipant({
transcriptId,
{
requestBody: {
name: participantInput,
},
);
});
setLoading(false);
assignTo(participant)().catch(() => {
// error and loading are handled by assignTo catch
@@ -240,8 +253,11 @@ const ParticipantList = ({
} else if (action == "Create") {
setLoading(true);
api
?.v1TranscriptAddParticipant(transcriptId, {
name: participantInput,
?.v1TranscriptAddParticipant({
transcriptId,
requestBody: {
name: participantInput,
},
})
.then(() => {
participants.refetch();
@@ -261,7 +277,7 @@ const ParticipantList = ({
if (loading || participants.loading || topicWithWords.loading) return;
setLoading(true);
api
?.v1TranscriptDeleteParticipant(transcriptId, participantId)
?.v1TranscriptDeleteParticipant({ transcriptId, participantId })
.then(() => {
participants.refetch();
setLoading(false);

View File

@@ -49,10 +49,10 @@ export default function FinalSummary(props: FinalSummaryProps) {
const requestBody: UpdateTranscript = {
long_summary: newSummary,
};
const updatedTranscript = await api?.v1TranscriptUpdate(
const updatedTranscript = await api?.v1TranscriptUpdate({
transcriptId,
requestBody,
);
});
console.log("Updated long summary:", updatedTranscript);
} catch (err) {
console.error("Failed to update long summary:", err);

View File

@@ -23,16 +23,19 @@ type TranscriptDetails = {
export default function TranscriptDetails(details: TranscriptDetails) {
const transcriptId = details.params.transcriptId;
const router = useRouter();
const statusToRedirect = ["idle", "recording", "processing"];
const transcript = useTranscript(transcriptId);
const transcriptStatus = transcript.response?.status;
const waiting = statusToRedirect.includes(transcriptStatus || "");
const topics = useTopics(transcriptId);
const waveform = useWaveform(transcriptId);
const waveform = useWaveform(transcriptId, waiting);
const useActiveTopic = useState<Topic | null>(null);
const mp3 = useMp3(transcriptId);
const mp3 = useMp3(transcriptId, waiting);
useEffect(() => {
const statusToRedirect = ["idle", "recording", "processing"];
if (statusToRedirect.includes(transcript.response?.status || "")) {
if (waiting) {
const newUrl = "/transcripts/" + details.params.transcriptId + "/record";
// Shallow redirection does not work on NextJS 13
// https://github.com/vercel/next.js/discussions/48110
@@ -40,7 +43,7 @@ export default function TranscriptDetails(details: TranscriptDetails) {
router.replace(newUrl);
// history.replaceState({}, "", newUrl);
}
}, [transcript.response?.status]);
}, [waiting]);
if (transcript.error || topics?.error) {
return (

View File

@@ -32,7 +32,7 @@ const TranscriptRecord = (details: TranscriptDetails) => {
const router = useRouter();
const [status, setStatus] = useState(
webSockets.status.value || transcript.response?.status || "idle"
webSockets.status.value || transcript.response?.status || "idle",
);
useEffect(() => {

View File

@@ -0,0 +1,113 @@
"use client";
import { useEffect, useState } from "react";
import useTranscript from "../../useTranscript";
import { useWebSockets } from "../../useWebSockets";
import "../../../../styles/button.css";
import { lockWakeState, releaseWakeState } from "../../../../lib/wakeLock";
import { useRouter } from "next/navigation";
import useMp3 from "../../useMp3";
import { Center, VStack, Text, Heading, Button } from "@chakra-ui/react";
import FileUploadButton from "../../fileUploadButton";
type TranscriptUpload = {
params: {
transcriptId: string;
};
};
const TranscriptUpload = (details: TranscriptUpload) => {
const transcript = useTranscript(details.params.transcriptId);
const [transcriptStarted, setTranscriptStarted] = useState(false);
const webSockets = useWebSockets(details.params.transcriptId);
let mp3 = useMp3(details.params.transcriptId, true);
const router = useRouter();
const [status, setStatus] = useState(
webSockets.status.value || transcript.response?.status || "idle",
);
useEffect(() => {
if (!transcriptStarted && webSockets.transcriptTextLive.length !== 0)
setTranscriptStarted(true);
}, [webSockets.transcriptTextLive]);
useEffect(() => {
//TODO HANDLE ERROR STATUS BETTER
const newStatus =
webSockets.status.value || transcript.response?.status || "idle";
setStatus(newStatus);
if (newStatus && (newStatus == "ended" || newStatus == "error")) {
console.log(newStatus, "redirecting");
const newUrl = "/transcripts/" + details.params.transcriptId;
router.replace(newUrl);
}
}, [webSockets.status.value, transcript.response?.status]);
useEffect(() => {
if (webSockets.waveform && webSockets.waveform) mp3.getNow();
}, [webSockets.waveform, webSockets.duration]);
useEffect(() => {
lockWakeState();
return () => {
releaseWakeState();
};
}, []);
return (
<>
<VStack
align={"left"}
w="full"
h="full"
mb={4}
background="gray.bg"
border={"2px solid"}
borderColor={"gray.bg"}
borderRadius={8}
p="4"
>
<Heading size={"lg"}>Upload meeting</Heading>
<Center h={"full"} w="full">
<VStack spacing={10}>
{status && status == "idle" && (
<>
<Text>
Please select the file, supported formats: .mp3, m4a, .wav,
.mp4, .mov or .webm
</Text>
<FileUploadButton transcriptId={details.params.transcriptId} />
</>
)}
{status && status == "uploaded" && (
<Text>File is uploaded, processing...</Text>
)}
{(status == "recording" || status == "processing") && (
<>
<Heading size={"lg"}>Processing your recording...</Heading>
<Text>
You can safely return to the library while your file is being
processed.
</Text>
<Button
colorScheme="blue"
onClick={() => {
router.push("/browse");
}}
>
Browse
</Button>
</>
)}
</VStack>
</Center>
</VStack>
</>
);
};
export default TranscriptUpload;

View File

@@ -24,7 +24,7 @@ const useCreateTranscript = (): UseCreateTranscript => {
setLoading(true);
api
.v1TranscriptsCreate(transcriptCreationDetails)
.v1TranscriptsCreate({ requestBody: transcriptCreationDetails })
.then((transcript) => {
setTranscript(transcript);
setLoading(false);

View File

@@ -1,16 +1,15 @@
import React from "react";
import React, { useState } from "react";
import useApi from "../../lib/useApi";
import { Button } from "@chakra-ui/react";
import { Button, CircularProgress } from "@chakra-ui/react";
type FileUploadButton = {
transcriptId: string;
disabled?: boolean;
};
export default function FileUploadButton(props: FileUploadButton) {
const fileInputRef = React.useRef<HTMLInputElement>(null);
const api = useApi();
const [progress, setProgress] = useState(0);
const triggerFileUpload = () => {
fileInputRef.current?.click();
};
@@ -27,7 +26,16 @@ export default function FileUploadButton(props: FileUploadButton) {
// Add other properties if required by the type definition
};
api?.v1TranscriptRecordUpload(props.transcriptId, uploadData);
api?.httpRequest.config.interceptors.request.use((request) => {
request.onUploadProgress = (progressEvent) => {
setProgress((progressEvent.progress || 0) * 100);
};
return request;
});
api?.v1TranscriptRecordUpload({
transcriptId: props.transcriptId,
formData: uploadData,
});
}
};
@@ -37,9 +45,16 @@ export default function FileUploadButton(props: FileUploadButton) {
onClick={triggerFileUpload}
colorScheme="blue"
mr={2}
isDisabled={props.disabled}
isDisabled={progress > 0}
>
Upload File
{progress > 0 && progress < 100 ? (
<>
Uploading...&nbsp;
<CircularProgress size="20px" value={progress} />
</>
) : (
<>Select File</>
)}
</Button>
<input

View File

@@ -12,7 +12,7 @@ import SelectSearch from "react-select-search";
import { supportedLatinLanguages } from "../../../supportedLanguages";
import { useFiefIsAuthenticated } from "@fief/fief/nextjs/react";
import { featureEnabled } from "../../domainContext";
import { Button, Text } from "@chakra-ui/react";
const TranscriptCreate = () => {
const router = useRouter();
const isAuthenticated = useFiefIsAuthenticated();
@@ -30,21 +30,29 @@ const TranscriptCreate = () => {
const createTranscript = useCreateTranscript();
const [loadingSend, setLoadingSend] = useState(false);
const [loadingRecord, setLoadingRecord] = useState(false);
const [loadingUpload, setLoadingUpload] = useState(false);
const send = () => {
if (loadingSend || createTranscript.loading || permissionDenied) return;
setLoadingSend(true);
if (loadingRecord || createTranscript.loading || permissionDenied) return;
setLoadingRecord(true);
createTranscript.create({ name, target_language: targetLanguage });
};
const uploadFile = () => {
if (loadingUpload || createTranscript.loading || permissionDenied) return;
setLoadingUpload(true);
createTranscript.create({ name, target_language: targetLanguage });
};
useEffect(() => {
const action = loadingRecord ? "record" : "upload";
createTranscript.transcript &&
router.push(`/transcripts/${createTranscript.transcript.id}/record`);
router.push(`/transcripts/${createTranscript.transcript.id}/${action}`);
}, [createTranscript.transcript]);
useEffect(() => {
if (createTranscript.error) setLoadingSend(false);
if (createTranscript.error) setLoadingRecord(false);
}, [createTranscript.error]);
const { loading, permissionOk, permissionDenied, requestPermission } =
@@ -55,10 +63,7 @@ const TranscriptCreate = () => {
<div className="lg:grid lg:grid-cols-2 lg:grid-rows-1 lg:gap-4 lg:h-full h-auto flex flex-col">
<section className="flex flex-col w-full lg:h-full items-center justify-evenly p-4 md:px-6 md:py-8">
<div className="flex flex-col max-w-xl items-center justify-center">
<h1 className="text-2xl font-bold mb-2">
Welcome to reflector.media
</h1>
<button>Test upload</button>
<h1 className="text-2xl font-bold mb-2">Welcome to Reflector</h1>
<p>
Reflector is a transcription and summarization pipeline that
transforms audio into knowledge.
@@ -101,7 +106,6 @@ const TranscriptCreate = () => {
/>
</div>
</label>
<label className="mb-3">
<p>Do you want to enable live translation?</p>
<SelectSearch
@@ -112,7 +116,6 @@ const TranscriptCreate = () => {
placeholder="Choose your language"
/>
</label>
{loading ? (
<p className="">Checking permissions...</p>
) : permissionOk ? (
@@ -131,13 +134,23 @@ const TranscriptCreate = () => {
Request Microphone Permission
</button>
)}
<button
className="mt-4 bg-blue-400 hover:bg-blue-500 focus-visible:bg-blue-500 text-white font-bold py-2 px-4 rounded"
<Button
colorScheme="blue"
onClick={send}
disabled={!permissionOk || loadingSend}
isDisabled={!permissionOk || loadingRecord || loadingUpload}
>
{loadingSend ? "Loading..." : "Confirm"}
</button>
{loadingRecord ? "Loading..." : "Record Meeting"}
</Button>
<Text align="center" m="2">
OR
</Text>
<Button
colorScheme="blue"
onClick={uploadFile}
isDisabled={!permissionOk || loadingRecord || loadingUpload}
>
{loadingUpload ? "Loading..." : "Upload File"}
</Button>
</div>
)}
</section>

View File

@@ -266,10 +266,6 @@ export default function Recorder(props: RecorderProps) {
mr={2}
onClick={handleRecClick}
/>
<FileUploadButton
transcriptId={props.transcriptId}
disabled={isRecording}
></FileUploadButton>
{!isRecording && (window as any).chrome && (
<IconButton
aria-label={"Record Tab"}

View File

@@ -41,8 +41,8 @@ export default function ShareAndPrivacy(props: ShareAndPrivacyProps) {
const [isOwner, setIsOwner] = useState(false);
const [shareMode, setShareMode] = useState<ShareOption>(
shareOptions.find(
(option) => option.value === props.transcriptResponse.share_mode
) || shareOptions[0]
(option) => option.value === props.transcriptResponse.share_mode,
) || shareOptions[0],
);
const [shareLoading, setShareLoading] = useState(false);
const requireLogin = featureEnabled("requireLogin");
@@ -57,14 +57,14 @@ export default function ShareAndPrivacy(props: ShareAndPrivacyProps) {
share_mode: toShareMode(selectedShareMode.value),
};
const updatedTranscript = await api.v1TranscriptUpdate(
props.transcriptResponse.id,
requestBody
);
const updatedTranscript = await api.v1TranscriptUpdate({
transcriptId: props.transcriptResponse.id,
requestBody,
});
setShareMode(
shareOptions.find(
(option) => option.value === updatedTranscript.share_mode
) || shareOptions[0]
(option) => option.value === updatedTranscript.share_mode,
) || shareOptions[0],
);
setShareLoading(false);
};

View File

@@ -42,7 +42,7 @@ export function TopicList({
const scrollToTopic = () => {
const topicDiv = document.getElementById(
`accordion-button-topic-${activeTopic?.id}`
`accordion-button-topic-${activeTopic?.id}`,
);
setTimeout(() => {
@@ -63,7 +63,7 @@ export function TopicList({
const toggleScroll = (element) => {
const bottom =
Math.abs(
element.scrollHeight - element.clientHeight - element.scrollTop
element.scrollHeight - element.clientHeight - element.scrollTop,
) < 2 || element.scrollHeight == element.clientHeight;
if (!bottom && autoscrollEnabled) {
setAutoscrollEnabled(false);
@@ -97,7 +97,7 @@ export function TopicList({
if (!participants.response) return;
return (
participants.response.find(
(participant) => participant.speaker == speakerNumber
(participant) => participant.speaker == speakerNumber,
)?.name || `Speaker ${speakerNumber}`
);
};
@@ -157,7 +157,7 @@ export function TopicList({
<AccordionButton
onClick={() => {
setActiveTopic(
activeTopic?.id == topic.id ? null : topic
activeTopic?.id == topic.id ? null : topic,
);
}}
>
@@ -200,7 +200,7 @@ export function TopicList({
fontSize={"sm"}
color={generateHighContrastColor(
`Speaker ${segment.speaker}`,
[96, 165, 250]
[96, 165, 250],
)}
>
{" "}

View File

@@ -21,10 +21,10 @@ const TranscriptTitle = (props: TranscriptTitle) => {
const requestBody: UpdateTranscript = {
title: newTitle,
};
const updatedTranscript = await api?.v1TranscriptUpdate(
const updatedTranscript = await api?.v1TranscriptUpdate({
transcriptId,
requestBody,
);
});
console.log("Updated transcript:", updatedTranscript);
} catch (err) {
console.error("Failed to update transcript:", err);

View File

@@ -49,7 +49,7 @@ const useParticipants = (transcriptId: string): UseParticipants => {
setLoading(true);
api
.v1TranscriptGetParticipants(transcriptId)
.v1TranscriptGetParticipants({ transcriptId })
.then((result) => {
setResponse(result);
setLoading(false);

View File

@@ -56,7 +56,7 @@ const useTopicWithWords = (
setLoading(true);
api
.v1TranscriptGetTopicsWithWordsPerSpeaker(transcriptId, topicId)
.v1TranscriptGetTopicsWithWordsPerSpeaker({ transcriptId, topicId })
.then((result) => {
setResponse(result);
setLoading(false);

View File

@@ -23,7 +23,7 @@ const useTopics = (id: string): TranscriptTopics => {
setLoading(true);
api
.v1TranscriptGetTopics(id)
.v1TranscriptGetTopics({ transcriptId: id })
.then((result) => {
setTopics(result);
setLoading(false);

View File

@@ -37,7 +37,7 @@ const useTranscript = (
setLoading(true);
api
.v1TranscriptGet(id)
.v1TranscriptGet({ transcriptId: id })
.then((result) => {
setResponse(result);
setLoading(false);

View File

@@ -28,7 +28,7 @@ const useTranscriptList = (page: number): TranscriptList => {
if (!api) return;
setLoading(true);
api
.v1TranscriptsList(page)
.v1TranscriptsList({ page })
.then((response) => {
setResponse(response);
setLoading(false);

View File

@@ -10,7 +10,7 @@ type AudioWaveFormResponse = {
error: Error | null;
};
const useWaveform = (id: string): AudioWaveFormResponse => {
const useWaveform = (id: string, waiting: boolean): AudioWaveFormResponse => {
const [waveform, setWaveform] = useState<AudioWaveform | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setErrorState] = useState<Error | null>(null);
@@ -18,10 +18,10 @@ const useWaveform = (id: string): AudioWaveFormResponse => {
const api = useApi();
useEffect(() => {
if (!id || !api) return;
if (!id || !api || waiting) return;
setLoading(true);
api
.v1TranscriptGetAudioWaveform(id)
.v1TranscriptGetAudioWaveform({ transcriptId: id })
.then((result) => {
setWaveform(result);
setLoading(false);
@@ -36,7 +36,7 @@ const useWaveform = (id: string): AudioWaveFormResponse => {
setError(err);
}
});
}, [id, api]);
}, [id, api, waiting]);
return { waveform, loading, error };
};

View File

@@ -41,7 +41,7 @@ const useWebRTC = (
};
api
.v1TranscriptRecordWebrtc(transcriptId, rtcOffer)
.v1TranscriptRecordWebrtc({ transcriptId, requestBody: rtcOffer })
.then((answer) => {
try {
p.signal(answer);

View File

@@ -316,7 +316,7 @@ export const useWebSockets = (transcriptId: string | null): UseWebSockets => {
if (!transcriptId || !api) return;
api?.v1TranscriptGetWebsocketEvents(transcriptId).then((result) => {});
api?.v1TranscriptGetWebsocketEvents({ transcriptId }).then((result) => {});
const url = `${websocket_url}/v1/transcripts/${transcriptId}/events`;
let ws = new WebSocket(url);

View File

@@ -1,23 +0,0 @@
# OpenAPI Generator Ignore
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
# Use this file to prevent files from being overwritten by the generator.
# The patterns follow closely to .gitignore or .dockerignore.
# As an example, the C# client generator defines ApiClient.cs.
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
#ApiClient.cs
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
#foo/*/qux
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
#foo/**/qux
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
# You can also negate patterns with an exclamation (!).
# For example, you can ignore all files in a docs folder with the file extension .md:
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md

View File

@@ -1,28 +0,0 @@
apis/DefaultApi.ts
apis/index.ts
index.ts
models/AudioWaveform.ts
models/CreateParticipant.ts
models/CreateTranscript.ts
models/DeletionStatus.ts
models/GetTranscript.ts
models/GetTranscriptSegmentTopic.ts
models/GetTranscriptTopic.ts
models/GetTranscriptTopicWithWords.ts
models/GetTranscriptTopicWithWordsPerSpeaker.ts
models/HTTPValidationError.ts
models/PageGetTranscript.ts
models/Participant.ts
models/RtcOffer.ts
models/SpeakerAssignment.ts
models/SpeakerAssignmentStatus.ts
models/SpeakerMerge.ts
models/SpeakerWords.ts
models/TranscriptParticipant.ts
models/UpdateParticipant.ts
models/UpdateTranscript.ts
models/UserInfo.ts
models/ValidationError.ts
models/Word.ts
models/index.ts
runtime.ts

View File

@@ -1 +0,0 @@
6.6.0

View File

@@ -1,36 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { BaseHttpRequest } from "./core/BaseHttpRequest";
import type { OpenAPIConfig } from "./core/OpenAPI";
import { FetchHttpRequest } from "./core/FetchHttpRequest";
import { DefaultService } from "./services/DefaultService";
type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
export class Api {
public readonly default: DefaultService;
public readonly request: BaseHttpRequest;
constructor(
config?: Partial<OpenAPIConfig>,
HttpRequest: HttpRequestConstructor = FetchHttpRequest,
) {
this.request = new HttpRequest({
BASE: config?.BASE ?? "",
VERSION: config?.VERSION ?? "0.1.0",
WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
CREDENTIALS: config?.CREDENTIALS ?? "include",
TOKEN: config?.TOKEN,
USERNAME: config?.USERNAME,
PASSWORD: config?.PASSWORD,
HEADERS: config?.HEADERS,
ENCODE_PATH: config?.ENCODE_PATH,
});
this.default = new DefaultService(this.request);
}
}

View File

@@ -1,12 +1,9 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { BaseHttpRequest } from "./core/BaseHttpRequest";
import type { OpenAPIConfig } from "./core/OpenAPI";
import { FetchHttpRequest } from "./core/FetchHttpRequest";
import { Interceptors } from "./core/OpenAPI";
import { AxiosHttpRequest } from "./core/AxiosHttpRequest";
import { DefaultService } from "./services/DefaultService";
import { DefaultService } from "./services.gen";
type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
@@ -17,7 +14,7 @@ export class OpenApi {
constructor(
config?: Partial<OpenAPIConfig>,
HttpRequest: HttpRequestConstructor = FetchHttpRequest,
HttpRequest: HttpRequestConstructor = AxiosHttpRequest,
) {
this.request = new HttpRequest({
BASE: config?.BASE ?? "",
@@ -29,6 +26,10 @@ export class OpenApi {
PASSWORD: config?.PASSWORD,
HEADERS: config?.HEADERS,
ENCODE_PATH: config?.ENCODE_PATH,
interceptors: {
request: config?.interceptors?.request ?? new Interceptors(),
response: config?.interceptors?.response ?? new Interceptors(),
},
});
this.default = new DefaultService(this.request);

View File

@@ -1,7 +1,3 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from "./ApiRequestOptions";
import type { ApiResult } from "./ApiResult";
@@ -9,7 +5,7 @@ export class ApiError extends Error {
public readonly url: string;
public readonly status: number;
public readonly statusText: string;
public readonly body: any;
public readonly body: unknown;
public readonly request: ApiRequestOptions;
constructor(

View File

@@ -1,8 +1,4 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ApiRequestOptions = {
export type ApiRequestOptions<T = unknown> = {
readonly method:
| "GET"
| "PUT"
@@ -12,13 +8,14 @@ export type ApiRequestOptions = {
| "HEAD"
| "PATCH";
readonly url: string;
readonly path?: Record<string, any>;
readonly cookies?: Record<string, any>;
readonly headers?: Record<string, any>;
readonly query?: Record<string, any>;
readonly formData?: Record<string, any>;
readonly path?: Record<string, unknown>;
readonly cookies?: Record<string, unknown>;
readonly headers?: Record<string, unknown>;
readonly query?: Record<string, unknown>;
readonly formData?: Record<string, unknown>;
readonly body?: any;
readonly mediaType?: string;
readonly responseHeader?: string;
readonly errors?: Record<number, string>;
readonly responseTransformer?: (data: unknown) => Promise<T>;
readonly errors?: Record<number | string, string>;
};

View File

@@ -1,11 +1,7 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ApiResult = {
readonly url: string;
export type ApiResult<TData = any> = {
readonly body: TData;
readonly ok: boolean;
readonly status: number;
readonly statusText: string;
readonly body: any;
readonly url: string;
};

View File

@@ -1,14 +1,10 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from "./ApiRequestOptions";
import { BaseHttpRequest } from "./BaseHttpRequest";
import type { CancelablePromise } from "./CancelablePromise";
import type { OpenAPIConfig } from "./OpenAPI";
import { request as __request } from "./request";
export class FetchHttpRequest extends BaseHttpRequest {
export class AxiosHttpRequest extends BaseHttpRequest {
constructor(config: OpenAPIConfig) {
super(config);
}
@@ -19,7 +15,9 @@ export class FetchHttpRequest extends BaseHttpRequest {
* @returns CancelablePromise<T>
* @throws ApiError
*/
public override request<T>(options: ApiRequestOptions): CancelablePromise<T> {
public override request<T>(
options: ApiRequestOptions<T>,
): CancelablePromise<T> {
return __request(this.config, options);
}
}

View File

@@ -1,7 +1,3 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApiRequestOptions } from "./ApiRequestOptions";
import type { CancelablePromise } from "./CancelablePromise";
import type { OpenAPIConfig } from "./OpenAPI";
@@ -9,5 +5,7 @@ import type { OpenAPIConfig } from "./OpenAPI";
export abstract class BaseHttpRequest {
constructor(public readonly config: OpenAPIConfig) {}
public abstract request<T>(options: ApiRequestOptions): CancelablePromise<T>;
public abstract request<T>(
options: ApiRequestOptions<T>,
): CancelablePromise<T>;
}

View File

@@ -1,7 +1,3 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export class CancelError extends Error {
constructor(message: string) {
super(message);
@@ -22,62 +18,62 @@ export interface OnCancel {
}
export class CancelablePromise<T> implements Promise<T> {
#isResolved: boolean;
#isRejected: boolean;
#isCancelled: boolean;
readonly #cancelHandlers: (() => void)[];
readonly #promise: Promise<T>;
#resolve?: (value: T | PromiseLike<T>) => void;
#reject?: (reason?: any) => void;
private _isResolved: boolean;
private _isRejected: boolean;
private _isCancelled: boolean;
readonly cancelHandlers: (() => void)[];
readonly promise: Promise<T>;
private _resolve?: (value: T | PromiseLike<T>) => void;
private _reject?: (reason?: unknown) => void;
constructor(
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
reject: (reason?: unknown) => void,
onCancel: OnCancel,
) => void,
) {
this.#isResolved = false;
this.#isRejected = false;
this.#isCancelled = false;
this.#cancelHandlers = [];
this.#promise = new Promise<T>((resolve, reject) => {
this.#resolve = resolve;
this.#reject = reject;
this._isResolved = false;
this._isRejected = false;
this._isCancelled = false;
this.cancelHandlers = [];
this.promise = new Promise<T>((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
const onResolve = (value: T | PromiseLike<T>): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
if (this._isResolved || this._isRejected || this._isCancelled) {
return;
}
this.#isResolved = true;
this.#resolve?.(value);
this._isResolved = true;
if (this._resolve) this._resolve(value);
};
const onReject = (reason?: any): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
const onReject = (reason?: unknown): void => {
if (this._isResolved || this._isRejected || this._isCancelled) {
return;
}
this.#isRejected = true;
this.#reject?.(reason);
this._isRejected = true;
if (this._reject) this._reject(reason);
};
const onCancel = (cancelHandler: () => void): void => {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
if (this._isResolved || this._isRejected || this._isCancelled) {
return;
}
this.#cancelHandlers.push(cancelHandler);
this.cancelHandlers.push(cancelHandler);
};
Object.defineProperty(onCancel, "isResolved", {
get: (): boolean => this.#isResolved,
get: (): boolean => this._isResolved,
});
Object.defineProperty(onCancel, "isRejected", {
get: (): boolean => this.#isRejected,
get: (): boolean => this._isRejected,
});
Object.defineProperty(onCancel, "isCancelled", {
get: (): boolean => this.#isCancelled,
get: (): boolean => this._isCancelled,
});
return executor(onResolve, onReject, onCancel as OnCancel);
@@ -90,29 +86,29 @@ export class CancelablePromise<T> implements Promise<T> {
public then<TResult1 = T, TResult2 = never>(
onFulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
onRejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null,
onRejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null,
): Promise<TResult1 | TResult2> {
return this.#promise.then(onFulfilled, onRejected);
return this.promise.then(onFulfilled, onRejected);
}
public catch<TResult = never>(
onRejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null,
onRejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null,
): Promise<T | TResult> {
return this.#promise.catch(onRejected);
return this.promise.catch(onRejected);
}
public finally(onFinally?: (() => void) | null): Promise<T> {
return this.#promise.finally(onFinally);
return this.promise.finally(onFinally);
}
public cancel(): void {
if (this.#isResolved || this.#isRejected || this.#isCancelled) {
if (this._isResolved || this._isRejected || this._isCancelled) {
return;
}
this.#isCancelled = true;
if (this.#cancelHandlers.length) {
this._isCancelled = true;
if (this.cancelHandlers.length) {
try {
for (const cancelHandler of this.#cancelHandlers) {
for (const cancelHandler of this.cancelHandlers) {
cancelHandler();
}
} catch (error) {
@@ -120,11 +116,11 @@ export class CancelablePromise<T> implements Promise<T> {
return;
}
}
this.#cancelHandlers.length = 0;
this.#reject?.(new CancelError("Request aborted"));
this.cancelHandlers.length = 0;
if (this._reject) this._reject(new CancelError("Request aborted"));
}
public get isCancelled(): boolean {
return this.#isCancelled;
return this._isCancelled;
}
}

View File

@@ -1,32 +1,57 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { AxiosRequestConfig, AxiosResponse } from "axios";
import type { ApiRequestOptions } from "./ApiRequestOptions";
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Headers = Record<string, string>;
type Middleware<T> = (value: T) => T | Promise<T>;
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
export class Interceptors<T> {
_fns: Middleware<T>[];
constructor() {
this._fns = [];
}
eject(fn: Middleware<T>): void {
const index = this._fns.indexOf(fn);
if (index !== -1) {
this._fns = [...this._fns.slice(0, index), ...this._fns.slice(index + 1)];
}
}
use(fn: Middleware<T>): void {
this._fns = [...this._fns, fn];
}
}
export type OpenAPIConfig = {
BASE: string;
VERSION: string;
WITH_CREDENTIALS: boolean;
CREDENTIALS: "include" | "omit" | "same-origin";
ENCODE_PATH?: ((path: string) => string) | undefined;
HEADERS?: Headers | Resolver<Headers> | undefined;
PASSWORD?: string | Resolver<string> | undefined;
TOKEN?: string | Resolver<string> | undefined;
USERNAME?: string | Resolver<string> | undefined;
PASSWORD?: string | Resolver<string> | undefined;
HEADERS?: Headers | Resolver<Headers> | undefined;
ENCODE_PATH?: ((path: string) => string) | undefined;
VERSION: string;
WITH_CREDENTIALS: boolean;
interceptors: {
request: Interceptors<AxiosRequestConfig>;
response: Interceptors<AxiosResponse>;
};
};
export const OpenAPI: OpenAPIConfig = {
BASE: "",
VERSION: "0.1.0",
WITH_CREDENTIALS: false,
CREDENTIALS: "include",
ENCODE_PATH: undefined,
HEADERS: undefined,
PASSWORD: undefined,
TOKEN: undefined,
USERNAME: undefined,
PASSWORD: undefined,
HEADERS: undefined,
ENCODE_PATH: undefined,
VERSION: "0.1.0",
WITH_CREDENTIALS: false,
interceptors: {
request: new Interceptors(),
response: new Interceptors(),
},
};

View File

@@ -1,7 +1,11 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import axios from "axios";
import type {
AxiosError,
AxiosRequestConfig,
AxiosResponse,
AxiosInstance,
} from "axios";
import { ApiError } from "./ApiError";
import type { ApiRequestOptions } from "./ApiRequestOptions";
import type { ApiResult } from "./ApiResult";
@@ -9,37 +13,26 @@ import { CancelablePromise } from "./CancelablePromise";
import type { OnCancel } from "./CancelablePromise";
import type { OpenAPIConfig } from "./OpenAPI";
export const isDefined = <T>(
value: T | null | undefined,
): value is Exclude<T, null | undefined> => {
return value !== undefined && value !== null;
};
export const isString = (value: any): value is string => {
export const isString = (value: unknown): value is string => {
return typeof value === "string";
};
export const isStringWithValue = (value: any): value is string => {
export const isStringWithValue = (value: unknown): value is string => {
return isString(value) && value !== "";
};
export const isBlob = (value: any): value is Blob => {
return (
typeof value === "object" &&
typeof value.type === "string" &&
typeof value.stream === "function" &&
typeof value.arrayBuffer === "function" &&
typeof value.constructor === "function" &&
typeof value.constructor.name === "string" &&
/^(Blob|File)$/.test(value.constructor.name) &&
/^(Blob|File)$/.test(value[Symbol.toStringTag])
);
return value instanceof Blob;
};
export const isFormData = (value: any): value is FormData => {
export const isFormData = (value: unknown): value is FormData => {
return value instanceof FormData;
};
export const isSuccess = (status: number): boolean => {
return status >= 200 && status < 300;
};
export const base64 = (str: string): string => {
try {
return btoa(str);
@@ -49,38 +42,32 @@ export const base64 = (str: string): string => {
}
};
export const getQueryString = (params: Record<string, any>): string => {
export const getQueryString = (params: Record<string, unknown>): string => {
const qs: string[] = [];
const append = (key: string, value: any) => {
const append = (key: string, value: unknown) => {
qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);
};
const process = (key: string, value: any) => {
if (isDefined(value)) {
if (Array.isArray(value)) {
value.forEach((v) => {
process(key, v);
});
} else if (typeof value === "object") {
Object.entries(value).forEach(([k, v]) => {
process(`${key}[${k}]`, v);
});
} else {
append(key, value);
}
const encodePair = (key: string, value: unknown) => {
if (value === undefined || value === null) {
return;
}
if (value instanceof Date) {
append(key, value.toISOString());
} else if (Array.isArray(value)) {
value.forEach((v) => encodePair(key, v));
} else if (typeof value === "object") {
Object.entries(value).forEach(([k, v]) => encodePair(`${key}[${k}]`, v));
} else {
append(key, value);
}
};
Object.entries(params).forEach(([key, value]) => {
process(key, value);
});
Object.entries(params).forEach(([key, value]) => encodePair(key, value));
if (qs.length > 0) {
return `?${qs.join("&")}`;
}
return "";
return qs.length ? `?${qs.join("&")}` : "";
};
const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
@@ -95,11 +82,8 @@ const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => {
return substring;
});
const url = `${config.BASE}${path}`;
if (options.query) {
return `${url}${getQueryString(options.query)}`;
}
return url;
const url = config.BASE + path;
return options.query ? url + getQueryString(options.query) : url;
};
export const getFormData = (
@@ -108,7 +92,7 @@ export const getFormData = (
if (options.formData) {
const formData = new FormData();
const process = (key: string, value: any) => {
const process = (key: string, value: unknown) => {
if (isString(value) || isBlob(value)) {
formData.append(key, value);
} else {
@@ -117,7 +101,7 @@ export const getFormData = (
};
Object.entries(options.formData)
.filter(([_, value]) => isDefined(value))
.filter(([, value]) => value !== undefined && value !== null)
.forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach((v) => process(key, v));
@@ -131,10 +115,10 @@ export const getFormData = (
return undefined;
};
type Resolver<T> = (options: ApiRequestOptions) => Promise<T>;
type Resolver<T> = (options: ApiRequestOptions<T>) => Promise<T>;
export const resolve = async <T>(
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
resolver?: T | Resolver<T>,
): Promise<T | undefined> => {
if (typeof resolver === "function") {
@@ -143,21 +127,27 @@ export const resolve = async <T>(
return resolver;
};
export const getHeaders = async (
export const getHeaders = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
): Promise<Headers> => {
const token = await resolve(options, config.TOKEN);
const username = await resolve(options, config.USERNAME);
const password = await resolve(options, config.PASSWORD);
const additionalHeaders = await resolve(options, config.HEADERS);
options: ApiRequestOptions<T>,
): Promise<Record<string, string>> => {
const [token, username, password, additionalHeaders] = await Promise.all([
// @ts-ignore
resolve(options, config.TOKEN),
// @ts-ignore
resolve(options, config.USERNAME),
// @ts-ignore
resolve(options, config.PASSWORD),
// @ts-ignore
resolve(options, config.HEADERS),
]);
const headers = Object.entries({
Accept: "application/json",
...additionalHeaders,
...options.headers,
})
.filter(([_, value]) => isDefined(value))
.filter(([, value]) => value !== undefined && value !== null)
.reduce(
(headers, [key, value]) => ({
...headers,
@@ -175,7 +165,7 @@ export const getHeaders = async (
headers["Authorization"] = `Basic ${credentials}`;
}
if (options.body) {
if (options.body !== undefined) {
if (options.mediaType) {
headers["Content-Type"] = options.mediaType;
} else if (isBlob(options.body)) {
@@ -185,61 +175,66 @@ export const getHeaders = async (
} else if (!isFormData(options.body)) {
headers["Content-Type"] = "application/json";
}
} else if (options.formData !== undefined) {
if (options.mediaType) {
headers["Content-Type"] = options.mediaType;
}
}
return new Headers(headers);
return headers;
};
export const getRequestBody = (options: ApiRequestOptions): any => {
if (options.body !== undefined) {
if (options.mediaType?.includes("/json")) {
return JSON.stringify(options.body);
} else if (
isString(options.body) ||
isBlob(options.body) ||
isFormData(options.body)
) {
return options.body;
} else {
return JSON.stringify(options.body);
}
export const getRequestBody = (options: ApiRequestOptions): unknown => {
if (options.body) {
return options.body;
}
return undefined;
};
export const sendRequest = async (
export const sendRequest = async <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
url: string,
body: any,
body: unknown,
formData: FormData | undefined,
headers: Headers,
headers: Record<string, string>,
onCancel: OnCancel,
): Promise<Response> => {
axiosClient: AxiosInstance,
): Promise<AxiosResponse<T>> => {
const controller = new AbortController();
const request: RequestInit = {
let requestConfig: AxiosRequestConfig = {
data: body ?? formData,
headers,
body: body ?? formData,
method: options.method,
signal: controller.signal,
url,
withCredentials: config.WITH_CREDENTIALS,
};
if (config.WITH_CREDENTIALS) {
request.credentials = config.CREDENTIALS;
}
onCancel(() => controller.abort());
return await fetch(url, request);
for (const fn of config.interceptors.request._fns) {
requestConfig = await fn(requestConfig);
}
try {
return await axiosClient.request(requestConfig);
} catch (error) {
const axiosError = error as AxiosError<T>;
if (axiosError.response) {
return axiosError.response;
}
throw error;
}
};
export const getResponseHeader = (
response: Response,
response: AxiosResponse<unknown>,
responseHeader?: string,
): string | undefined => {
if (responseHeader) {
const content = response.headers.get(responseHeader);
const content = response.headers[responseHeader];
if (isString(content)) {
return content;
}
@@ -247,24 +242,9 @@ export const getResponseHeader = (
return undefined;
};
export const getResponseBody = async (response: Response): Promise<any> => {
export const getResponseBody = (response: AxiosResponse<unknown>): unknown => {
if (response.status !== 204) {
try {
const contentType = response.headers.get("Content-Type");
if (contentType) {
const jsonTypes = ["application/json", "application/problem+json"];
const isJSON = jsonTypes.some((type) =>
contentType.toLowerCase().startsWith(type),
);
if (isJSON) {
return await response.json();
} else {
return await response.text();
}
}
} catch (error) {
console.error(error);
}
return response.data;
}
return undefined;
};
@@ -276,11 +256,44 @@ export const catchErrorCodes = (
const errors: Record<number, string> = {
400: "Bad Request",
401: "Unauthorized",
402: "Payment Required",
403: "Forbidden",
404: "Not Found",
405: "Method Not Allowed",
406: "Not Acceptable",
407: "Proxy Authentication Required",
408: "Request Timeout",
409: "Conflict",
410: "Gone",
411: "Length Required",
412: "Precondition Failed",
413: "Payload Too Large",
414: "URI Too Long",
415: "Unsupported Media Type",
416: "Range Not Satisfiable",
417: "Expectation Failed",
418: "Im a teapot",
421: "Misdirected Request",
422: "Unprocessable Content",
423: "Locked",
424: "Failed Dependency",
425: "Too Early",
426: "Upgrade Required",
428: "Precondition Required",
429: "Too Many Requests",
431: "Request Header Fields Too Large",
451: "Unavailable For Legal Reasons",
500: "Internal Server Error",
501: "Not Implemented",
502: "Bad Gateway",
503: "Service Unavailable",
504: "Gateway Timeout",
505: "HTTP Version Not Supported",
506: "Variant Also Negotiates",
507: "Insufficient Storage",
508: "Loop Detected",
510: "Not Extended",
511: "Network Authentication Required",
...options.errors,
};
@@ -312,12 +325,14 @@ export const catchErrorCodes = (
* Request method
* @param config The OpenAPI configuration object
* @param options The request options from the service
* @param axiosClient The axios client instance to use
* @returns CancelablePromise<T>
* @throws ApiError
*/
export const request = <T>(
config: OpenAPIConfig,
options: ApiRequestOptions,
options: ApiRequestOptions<T>,
axiosClient: AxiosInstance = axios,
): CancelablePromise<T> => {
return new CancelablePromise(async (resolve, reject, onCancel) => {
try {
@@ -327,7 +342,7 @@ export const request = <T>(
const headers = await getHeaders(config, options);
if (!onCancel.isCancelled) {
const response = await sendRequest(
let response = await sendRequest<T>(
config,
options,
url,
@@ -335,19 +350,30 @@ export const request = <T>(
formData,
headers,
onCancel,
axiosClient,
);
const responseBody = await getResponseBody(response);
for (const fn of config.interceptors.response._fns) {
response = await fn(response);
}
const responseBody = getResponseBody(response);
const responseHeader = getResponseHeader(
response,
options.responseHeader,
);
let transformedBody = responseBody;
if (options.responseTransformer && isSuccess(response.status)) {
transformedBody = await options.responseTransformer(responseBody);
}
const result: ApiResult = {
url,
ok: response.ok,
ok: isSuccess(response.status),
status: response.status,
statusText: response.statusText,
body: responseHeader ?? responseBody,
body: responseHeader ?? transformedBody,
};
catchErrorCodes(options, result);

View File

@@ -1,38 +1,9 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
// This file is auto-generated by @hey-api/openapi-ts
export { OpenApi } from "./OpenApi";
export { ApiError } from "./core/ApiError";
export { BaseHttpRequest } from "./core/BaseHttpRequest";
export { CancelablePromise, CancelError } from "./core/CancelablePromise";
export { OpenAPI } from "./core/OpenAPI";
export type { OpenAPIConfig } from "./core/OpenAPI";
export type { AudioWaveform } from "./models/AudioWaveform";
export type { Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post } from "./models/Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post";
export type { CreateParticipant } from "./models/CreateParticipant";
export type { CreateTranscript } from "./models/CreateTranscript";
export type { DeletionStatus } from "./models/DeletionStatus";
export type { GetTranscript } from "./models/GetTranscript";
export type { GetTranscriptSegmentTopic } from "./models/GetTranscriptSegmentTopic";
export type { GetTranscriptTopic } from "./models/GetTranscriptTopic";
export type { GetTranscriptTopicWithWords } from "./models/GetTranscriptTopicWithWords";
export type { GetTranscriptTopicWithWordsPerSpeaker } from "./models/GetTranscriptTopicWithWordsPerSpeaker";
export type { HTTPValidationError } from "./models/HTTPValidationError";
export type { Page_GetTranscript_ } from "./models/Page_GetTranscript_";
export type { Participant } from "./models/Participant";
export type { RtcOffer } from "./models/RtcOffer";
export type { SpeakerAssignment } from "./models/SpeakerAssignment";
export type { SpeakerAssignmentStatus } from "./models/SpeakerAssignmentStatus";
export type { SpeakerMerge } from "./models/SpeakerMerge";
export type { SpeakerWords } from "./models/SpeakerWords";
export type { TranscriptParticipant } from "./models/TranscriptParticipant";
export type { UpdateParticipant } from "./models/UpdateParticipant";
export type { UpdateTranscript } from "./models/UpdateTranscript";
export type { UserInfo } from "./models/UserInfo";
export type { ValidationError } from "./models/ValidationError";
export type { Word } from "./models/Word";
export { DefaultService } from "./services/DefaultService";
export { OpenAPI, type OpenAPIConfig } from "./core/OpenAPI";
export * from "./schemas.gen";
export * from "./services.gen";
export * from "./types.gen";

View File

@@ -1,8 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type AudioWaveform = {
data: Array<number>;
};

View File

@@ -1,9 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post =
{
file: Blob;
};

View File

@@ -1,9 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreateParticipant = {
speaker?: number | null;
name: string;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type CreateTranscript = {
name: string;
source_language?: string;
target_language?: string;
};

View File

@@ -1,8 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type DeletionStatus = {
status: string;
};

View File

@@ -1,24 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { TranscriptParticipant } from "./TranscriptParticipant";
export type GetTranscript = {
id: string;
user_id: string | null;
name: string;
status: string;
locked: boolean;
duration: number;
title: string | null;
short_summary: string | null;
long_summary: string | null;
created_at: string;
share_mode?: string;
source_language: string | null;
target_language: string | null;
participants: Array<TranscriptParticipant> | null;
reviewed: boolean;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type GetTranscriptSegmentTopic = {
text: string;
start: number;
speaker: number;
};

View File

@@ -1,16 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { GetTranscriptSegmentTopic } from "./GetTranscriptSegmentTopic";
export type GetTranscriptTopic = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
};

View File

@@ -1,18 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { GetTranscriptSegmentTopic } from "./GetTranscriptSegmentTopic";
import type { Word } from "./Word";
export type GetTranscriptTopicWithWords = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
words?: Array<Word>;
};

View File

@@ -1,18 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { GetTranscriptSegmentTopic } from "./GetTranscriptSegmentTopic";
import type { SpeakerWords } from "./SpeakerWords";
export type GetTranscriptTopicWithWordsPerSpeaker = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
words_per_speaker?: Array<SpeakerWords>;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ValidationError } from "./ValidationError";
export type HTTPValidationError = {
detail?: Array<ValidationError>;
};

View File

@@ -1,14 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { GetTranscript } from "./GetTranscript";
export type Page_GetTranscript_ = {
items: Array<GetTranscript>;
total: number;
page: number | null;
size: number | null;
pages?: number | null;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type Participant = {
id: string;
speaker: number | null;
name: string;
};

View File

@@ -1,9 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type RtcOffer = {
sdp: string;
type: string;
};

View File

@@ -1,11 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type SpeakerAssignment = {
speaker?: number | null;
participant?: string | null;
timestamp_from: number;
timestamp_to: number;
};

View File

@@ -1,8 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type SpeakerAssignmentStatus = {
status: string;
};

View File

@@ -1,9 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type SpeakerMerge = {
speaker_from: number;
speaker_to: number;
};

View File

@@ -1,11 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { Word } from "./Word";
export type SpeakerWords = {
speaker: number;
words: Array<Word>;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type TranscriptParticipant = {
id?: string;
speaker: number | null;
name: string;
};

View File

@@ -1,9 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UpdateParticipant = {
speaker?: number | null;
name?: string | null;
};

View File

@@ -1,17 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { TranscriptParticipant } from "./TranscriptParticipant";
export type UpdateTranscript = {
name?: string | null;
locked?: boolean | null;
title?: string | null;
short_summary?: string | null;
long_summary?: string | null;
share_mode?: "public" | "semi-private" | "private" | null;
participants?: Array<TranscriptParticipant> | null;
reviewed?: boolean | null;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type UserInfo = {
sub: string;
email: string | null;
email_verified: boolean | null;
};

View File

@@ -1,10 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type ValidationError = {
loc: Array<string | number>;
msg: string;
type: string;
};

View File

@@ -1,11 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
export type Word = {
text: string;
start: number;
end: number;
speaker?: number;
};

View File

@@ -1,520 +0,0 @@
/* tslint:disable */
/* eslint-disable */
/**
* FastAPI
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
*
* The version of the OpenAPI document: 0.1.0
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
export const BASE_PATH = "http://localhost".replace(/\/+$/, "");
export interface ConfigurationParameters {
basePath?: string; // override base path
fetchApi?: FetchAPI; // override for fetch implementation
middleware?: Middleware[]; // middleware to apply before/after fetch requests
queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings
username?: string; // parameter for basic security
password?: string; // parameter for basic security
apiKey?: string | ((name: string) => string); // parameter for apiKey security
accessToken?:
| string
| Promise<string>
| ((name?: string, scopes?: string[]) => string | Promise<string>); // parameter for oauth2 security
headers?: HTTPHeaders; //header params we want to use on every request
credentials?: RequestCredentials; //value for the credentials param we want to use on each request
}
export class Configuration {
constructor(private configuration: ConfigurationParameters = {}) {}
set config(configuration: Configuration) {
this.configuration = configuration;
}
get basePath(): string {
return this.configuration.basePath != null
? this.configuration.basePath
: BASE_PATH;
}
get fetchApi(): FetchAPI | undefined {
return this.configuration.fetchApi;
}
get middleware(): Middleware[] {
return this.configuration.middleware || [];
}
get queryParamsStringify(): (params: HTTPQuery) => string {
return this.configuration.queryParamsStringify || querystring;
}
get username(): string | undefined {
return this.configuration.username;
}
get password(): string | undefined {
return this.configuration.password;
}
get apiKey(): ((name: string) => string) | undefined {
const apiKey = this.configuration.apiKey;
if (apiKey) {
return typeof apiKey === "function" ? apiKey : () => apiKey;
}
return undefined;
}
get accessToken():
| ((name?: string, scopes?: string[]) => string | Promise<string>)
| undefined {
const accessToken = this.configuration.accessToken;
if (accessToken) {
return typeof accessToken === "function"
? accessToken
: async () => accessToken;
}
return undefined;
}
get headers(): HTTPHeaders | undefined {
return this.configuration.headers;
}
get credentials(): RequestCredentials | undefined {
return this.configuration.credentials;
}
}
export const DefaultConfig = new Configuration();
/**
* This is the base class for all generated API classes.
*/
export class BaseAPI {
private static readonly jsonRegex = new RegExp(
"^(:?application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$",
"i",
);
private middleware: Middleware[];
constructor(protected configuration = DefaultConfig) {
this.middleware = configuration.middleware;
}
withMiddleware<T extends BaseAPI>(this: T, ...middlewares: Middleware[]) {
const next = this.clone<T>();
next.middleware = next.middleware.concat(...middlewares);
return next;
}
withPreMiddleware<T extends BaseAPI>(
this: T,
...preMiddlewares: Array<Middleware["pre"]>
) {
const middlewares = preMiddlewares.map((pre) => ({ pre }));
return this.withMiddleware<T>(...middlewares);
}
withPostMiddleware<T extends BaseAPI>(
this: T,
...postMiddlewares: Array<Middleware["post"]>
) {
const middlewares = postMiddlewares.map((post) => ({ post }));
return this.withMiddleware<T>(...middlewares);
}
/**
* Check if the given MIME is a JSON MIME.
* JSON MIME examples:
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
* application/vnd.company+json
* @param mime - MIME (Multipurpose Internet Mail Extensions)
* @return True if the given MIME is JSON, false otherwise.
*/
protected isJsonMime(mime: string | null | undefined): boolean {
if (!mime) {
return false;
}
return BaseAPI.jsonRegex.test(mime);
}
protected async request(
context: RequestOpts,
initOverrides?: RequestInit | InitOverrideFunction,
): Promise<Response> {
const { url, init } = await this.createFetchParams(context, initOverrides);
const response = await this.fetchApi(url, init);
if (response && response.status >= 200 && response.status < 300) {
return response;
}
throw new ResponseError(response, "Response returned an error code");
}
private async createFetchParams(
context: RequestOpts,
initOverrides?: RequestInit | InitOverrideFunction,
) {
let url = this.configuration.basePath + context.path;
if (
context.query !== undefined &&
Object.keys(context.query).length !== 0
) {
// only add the querystring to the URL if there are query parameters.
// this is done to avoid urls ending with a "?" character which buggy webservers
// do not handle correctly sometimes.
url += "?" + this.configuration.queryParamsStringify(context.query);
}
const headers = Object.assign(
{},
this.configuration.headers,
context.headers,
);
Object.keys(headers).forEach((key) =>
headers[key] === undefined ? delete headers[key] : {},
);
const initOverrideFn =
typeof initOverrides === "function"
? initOverrides
: async () => initOverrides;
const initParams = {
method: context.method,
headers,
body: context.body,
credentials: this.configuration.credentials,
};
const overriddenInit: RequestInit = {
...initParams,
...(await initOverrideFn({
init: initParams,
context,
})),
};
const init: RequestInit = {
...overriddenInit,
body:
isFormData(overriddenInit.body) ||
overriddenInit.body instanceof URLSearchParams ||
isBlob(overriddenInit.body)
? overriddenInit.body
: JSON.stringify(overriddenInit.body),
};
return { url, init };
}
private fetchApi = async (url: string, init: RequestInit) => {
let fetchParams = { url, init };
for (const middleware of this.middleware) {
if (middleware.pre) {
fetchParams =
(await middleware.pre({
fetch: this.fetchApi,
...fetchParams,
})) || fetchParams;
}
}
let response: Response | undefined = undefined;
try {
response = await (this.configuration.fetchApi || fetch)(
fetchParams.url,
fetchParams.init,
);
} catch (e) {
for (const middleware of this.middleware) {
if (middleware.onError) {
response =
(await middleware.onError({
fetch: this.fetchApi,
url: fetchParams.url,
init: fetchParams.init,
error: e,
response: response ? response.clone() : undefined,
})) || response;
}
}
if (response === undefined) {
if (e instanceof Error) {
throw new FetchError(
e,
"The request failed and the interceptors did not return an alternative response",
);
} else {
throw e;
}
}
}
for (const middleware of this.middleware) {
if (middleware.post) {
response =
(await middleware.post({
fetch: this.fetchApi,
url: fetchParams.url,
init: fetchParams.init,
response: response.clone(),
})) || response;
}
}
return response;
};
/**
* Create a shallow clone of `this` by constructing a new instance
* and then shallow cloning data members.
*/
private clone<T extends BaseAPI>(this: T): T {
const constructor = this.constructor as any;
const next = new constructor(this.configuration);
next.middleware = this.middleware.slice();
return next;
}
}
function isBlob(value: any): value is Blob {
return typeof Blob !== "undefined" && value instanceof Blob;
}
function isFormData(value: any): value is FormData {
return typeof FormData !== "undefined" && value instanceof FormData;
}
export class ResponseError extends Error {
override name: "ResponseError" = "ResponseError";
constructor(
public response: Response,
msg?: string,
) {
super(msg);
}
}
export class FetchError extends Error {
override name: "FetchError" = "FetchError";
constructor(
public cause: Error,
msg?: string,
) {
super(msg);
}
}
export class RequiredError extends Error {
override name: "RequiredError" = "RequiredError";
constructor(
public field: string,
msg?: string,
) {
super(msg);
}
}
export const COLLECTION_FORMATS = {
csv: ",",
ssv: " ",
tsv: "\t",
pipes: "|",
};
export type FetchAPI = WindowOrWorkerGlobalScope["fetch"];
export type Json = any;
export type HTTPMethod =
| "GET"
| "POST"
| "PUT"
| "PATCH"
| "DELETE"
| "OPTIONS"
| "HEAD";
export type HTTPHeaders = { [key: string]: string };
export type HTTPQuery = {
[key: string]:
| string
| number
| null
| boolean
| Array<string | number | null | boolean>
| Set<string | number | null | boolean>
| HTTPQuery;
};
export type HTTPBody = Json | FormData | URLSearchParams;
export type HTTPRequestInit = {
headers?: HTTPHeaders;
method: HTTPMethod;
credentials?: RequestCredentials;
body?: HTTPBody;
};
export type ModelPropertyNaming =
| "camelCase"
| "snake_case"
| "PascalCase"
| "original";
export type InitOverrideFunction = (requestContext: {
init: HTTPRequestInit;
context: RequestOpts;
}) => Promise<RequestInit>;
export interface FetchParams {
url: string;
init: RequestInit;
}
export interface RequestOpts {
path: string;
method: HTTPMethod;
headers: HTTPHeaders;
query?: HTTPQuery;
body?: HTTPBody;
}
export function exists(json: any, key: string) {
const value = json[key];
return value !== null && value !== undefined;
}
export function querystring(params: HTTPQuery, prefix: string = ""): string {
return Object.keys(params)
.map((key) => querystringSingleKey(key, params[key], prefix))
.filter((part) => part.length > 0)
.join("&");
}
function querystringSingleKey(
key: string,
value:
| string
| number
| null
| undefined
| boolean
| Array<string | number | null | boolean>
| Set<string | number | null | boolean>
| HTTPQuery,
keyPrefix: string = "",
): string {
const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key);
if (value instanceof Array) {
const multiValue = value
.map((singleValue) => encodeURIComponent(String(singleValue)))
.join(`&${encodeURIComponent(fullKey)}=`);
return `${encodeURIComponent(fullKey)}=${multiValue}`;
}
if (value instanceof Set) {
const valueAsArray = Array.from(value);
return querystringSingleKey(key, valueAsArray, keyPrefix);
}
if (value instanceof Date) {
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(
value.toISOString(),
)}`;
}
if (value instanceof Object) {
return querystring(value as HTTPQuery, fullKey);
}
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`;
}
export function mapValues(data: any, fn: (item: any) => any) {
return Object.keys(data).reduce(
(acc, key) => ({ ...acc, [key]: fn(data[key]) }),
{},
);
}
export function canConsumeForm(consumes: Consume[]): boolean {
for (const consume of consumes) {
if ("multipart/form-data" === consume.contentType) {
return true;
}
}
return false;
}
export interface Consume {
contentType: string;
}
export interface RequestContext {
fetch: FetchAPI;
url: string;
init: RequestInit;
}
export interface ResponseContext {
fetch: FetchAPI;
url: string;
init: RequestInit;
response: Response;
}
export interface ErrorContext {
fetch: FetchAPI;
url: string;
init: RequestInit;
error: unknown;
response?: Response;
}
export interface Middleware {
pre?(context: RequestContext): Promise<FetchParams | void>;
post?(context: ResponseContext): Promise<Response | void>;
onError?(context: ErrorContext): Promise<Response | void>;
}
export interface ApiResponse<T> {
raw: Response;
value(): Promise<T>;
}
export interface ResponseTransformer<T> {
(json: any): T;
}
export class JSONApiResponse<T> {
constructor(
public raw: Response,
private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue,
) {}
async value(): Promise<T> {
return this.transformer(await this.raw.json());
}
}
export class VoidApiResponse {
constructor(public raw: Response) {}
async value(): Promise<void> {
return undefined;
}
}
export class BlobApiResponse {
constructor(public raw: Response) {}
async value(): Promise<Blob> {
return await this.raw.blob();
}
}
export class TextApiResponse {
constructor(public raw: Response) {}
async value(): Promise<string> {
return await this.raw.text();
}
}

845
www/app/api/schemas.gen.ts Normal file
View File

@@ -0,0 +1,845 @@
// This file is auto-generated by @hey-api/openapi-ts
export const $AudioWaveform = {
properties: {
data: {
items: {
type: "number",
},
type: "array",
title: "Data",
},
},
type: "object",
required: ["data"],
title: "AudioWaveform",
} as const;
export const $Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post =
{
properties: {
file: {
type: "string",
format: "binary",
title: "File",
},
},
type: "object",
required: ["file"],
title:
"Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post",
} as const;
export const $CreateParticipant = {
properties: {
speaker: {
anyOf: [
{
type: "integer",
},
{
type: "null",
},
],
title: "Speaker",
},
name: {
type: "string",
title: "Name",
},
},
type: "object",
required: ["name"],
title: "CreateParticipant",
} as const;
export const $CreateTranscript = {
properties: {
name: {
type: "string",
title: "Name",
},
source_language: {
type: "string",
title: "Source Language",
default: "en",
},
target_language: {
type: "string",
title: "Target Language",
default: "en",
},
},
type: "object",
required: ["name"],
title: "CreateTranscript",
} as const;
export const $DeletionStatus = {
properties: {
status: {
type: "string",
title: "Status",
},
},
type: "object",
required: ["status"],
title: "DeletionStatus",
} as const;
export const $GetTranscript = {
properties: {
id: {
type: "string",
title: "Id",
},
user_id: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "User Id",
},
name: {
type: "string",
title: "Name",
},
status: {
type: "string",
title: "Status",
},
locked: {
type: "boolean",
title: "Locked",
},
duration: {
type: "number",
title: "Duration",
},
title: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Title",
},
short_summary: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Short Summary",
},
long_summary: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Long Summary",
},
created_at: {
type: "string",
format: "date-time",
title: "Created At",
},
share_mode: {
type: "string",
title: "Share Mode",
default: "private",
},
source_language: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Source Language",
},
target_language: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Target Language",
},
participants: {
anyOf: [
{
items: {
$ref: "#/components/schemas/TranscriptParticipant",
},
type: "array",
},
{
type: "null",
},
],
title: "Participants",
},
reviewed: {
type: "boolean",
title: "Reviewed",
},
},
type: "object",
required: [
"id",
"user_id",
"name",
"status",
"locked",
"duration",
"title",
"short_summary",
"long_summary",
"created_at",
"source_language",
"target_language",
"participants",
"reviewed",
],
title: "GetTranscript",
} as const;
export const $GetTranscriptSegmentTopic = {
properties: {
text: {
type: "string",
title: "Text",
},
start: {
type: "number",
title: "Start",
},
speaker: {
type: "integer",
title: "Speaker",
},
},
type: "object",
required: ["text", "start", "speaker"],
title: "GetTranscriptSegmentTopic",
} as const;
export const $GetTranscriptTopic = {
properties: {
id: {
type: "string",
title: "Id",
},
title: {
type: "string",
title: "Title",
},
summary: {
type: "string",
title: "Summary",
},
timestamp: {
type: "number",
title: "Timestamp",
},
duration: {
anyOf: [
{
type: "number",
},
{
type: "null",
},
],
title: "Duration",
},
transcript: {
type: "string",
title: "Transcript",
},
segments: {
items: {
$ref: "#/components/schemas/GetTranscriptSegmentTopic",
},
type: "array",
title: "Segments",
default: [],
},
},
type: "object",
required: ["id", "title", "summary", "timestamp", "duration", "transcript"],
title: "GetTranscriptTopic",
} as const;
export const $GetTranscriptTopicWithWords = {
properties: {
id: {
type: "string",
title: "Id",
},
title: {
type: "string",
title: "Title",
},
summary: {
type: "string",
title: "Summary",
},
timestamp: {
type: "number",
title: "Timestamp",
},
duration: {
anyOf: [
{
type: "number",
},
{
type: "null",
},
],
title: "Duration",
},
transcript: {
type: "string",
title: "Transcript",
},
segments: {
items: {
$ref: "#/components/schemas/GetTranscriptSegmentTopic",
},
type: "array",
title: "Segments",
default: [],
},
words: {
items: {
$ref: "#/components/schemas/Word",
},
type: "array",
title: "Words",
default: [],
},
},
type: "object",
required: ["id", "title", "summary", "timestamp", "duration", "transcript"],
title: "GetTranscriptTopicWithWords",
} as const;
export const $GetTranscriptTopicWithWordsPerSpeaker = {
properties: {
id: {
type: "string",
title: "Id",
},
title: {
type: "string",
title: "Title",
},
summary: {
type: "string",
title: "Summary",
},
timestamp: {
type: "number",
title: "Timestamp",
},
duration: {
anyOf: [
{
type: "number",
},
{
type: "null",
},
],
title: "Duration",
},
transcript: {
type: "string",
title: "Transcript",
},
segments: {
items: {
$ref: "#/components/schemas/GetTranscriptSegmentTopic",
},
type: "array",
title: "Segments",
default: [],
},
words_per_speaker: {
items: {
$ref: "#/components/schemas/SpeakerWords",
},
type: "array",
title: "Words Per Speaker",
default: [],
},
},
type: "object",
required: ["id", "title", "summary", "timestamp", "duration", "transcript"],
title: "GetTranscriptTopicWithWordsPerSpeaker",
} as const;
export const $HTTPValidationError = {
properties: {
detail: {
items: {
$ref: "#/components/schemas/ValidationError",
},
type: "array",
title: "Detail",
},
},
type: "object",
title: "HTTPValidationError",
} as const;
export const $Page_GetTranscript_ = {
properties: {
items: {
items: {
$ref: "#/components/schemas/GetTranscript",
},
type: "array",
title: "Items",
},
total: {
type: "integer",
minimum: 0,
title: "Total",
},
page: {
anyOf: [
{
type: "integer",
minimum: 1,
},
{
type: "null",
},
],
title: "Page",
},
size: {
anyOf: [
{
type: "integer",
minimum: 1,
},
{
type: "null",
},
],
title: "Size",
},
pages: {
anyOf: [
{
type: "integer",
minimum: 0,
},
{
type: "null",
},
],
title: "Pages",
},
},
type: "object",
required: ["items", "total", "page", "size"],
title: "Page[GetTranscript]",
} as const;
export const $Participant = {
properties: {
id: {
type: "string",
title: "Id",
},
speaker: {
anyOf: [
{
type: "integer",
},
{
type: "null",
},
],
title: "Speaker",
},
name: {
type: "string",
title: "Name",
},
},
type: "object",
required: ["id", "speaker", "name"],
title: "Participant",
} as const;
export const $RtcOffer = {
properties: {
sdp: {
type: "string",
title: "Sdp",
},
type: {
type: "string",
title: "Type",
},
},
type: "object",
required: ["sdp", "type"],
title: "RtcOffer",
} as const;
export const $SpeakerAssignment = {
properties: {
speaker: {
anyOf: [
{
type: "integer",
minimum: 0,
},
{
type: "null",
},
],
title: "Speaker",
},
participant: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Participant",
},
timestamp_from: {
type: "number",
title: "Timestamp From",
},
timestamp_to: {
type: "number",
title: "Timestamp To",
},
},
type: "object",
required: ["timestamp_from", "timestamp_to"],
title: "SpeakerAssignment",
} as const;
export const $SpeakerAssignmentStatus = {
properties: {
status: {
type: "string",
title: "Status",
},
},
type: "object",
required: ["status"],
title: "SpeakerAssignmentStatus",
} as const;
export const $SpeakerMerge = {
properties: {
speaker_from: {
type: "integer",
title: "Speaker From",
},
speaker_to: {
type: "integer",
title: "Speaker To",
},
},
type: "object",
required: ["speaker_from", "speaker_to"],
title: "SpeakerMerge",
} as const;
export const $SpeakerWords = {
properties: {
speaker: {
type: "integer",
title: "Speaker",
},
words: {
items: {
$ref: "#/components/schemas/Word",
},
type: "array",
title: "Words",
},
},
type: "object",
required: ["speaker", "words"],
title: "SpeakerWords",
} as const;
export const $TranscriptParticipant = {
properties: {
id: {
type: "string",
title: "Id",
},
speaker: {
anyOf: [
{
type: "integer",
},
{
type: "null",
},
],
title: "Speaker",
},
name: {
type: "string",
title: "Name",
},
},
type: "object",
required: ["speaker", "name"],
title: "TranscriptParticipant",
} as const;
export const $UpdateParticipant = {
properties: {
speaker: {
anyOf: [
{
type: "integer",
},
{
type: "null",
},
],
title: "Speaker",
},
name: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Name",
},
},
type: "object",
title: "UpdateParticipant",
} as const;
export const $UpdateTranscript = {
properties: {
name: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Name",
},
locked: {
anyOf: [
{
type: "boolean",
},
{
type: "null",
},
],
title: "Locked",
},
title: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Title",
},
short_summary: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Short Summary",
},
long_summary: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Long Summary",
},
share_mode: {
anyOf: [
{
type: "string",
enum: ["public", "semi-private", "private"],
},
{
type: "null",
},
],
title: "Share Mode",
},
participants: {
anyOf: [
{
items: {
$ref: "#/components/schemas/TranscriptParticipant",
},
type: "array",
},
{
type: "null",
},
],
title: "Participants",
},
reviewed: {
anyOf: [
{
type: "boolean",
},
{
type: "null",
},
],
title: "Reviewed",
},
},
type: "object",
title: "UpdateTranscript",
} as const;
export const $UserInfo = {
properties: {
sub: {
type: "string",
title: "Sub",
},
email: {
anyOf: [
{
type: "string",
},
{
type: "null",
},
],
title: "Email",
},
email_verified: {
anyOf: [
{
type: "boolean",
},
{
type: "null",
},
],
title: "Email Verified",
},
},
type: "object",
required: ["sub", "email", "email_verified"],
title: "UserInfo",
} as const;
export const $ValidationError = {
properties: {
loc: {
items: {
anyOf: [
{
type: "string",
},
{
type: "integer",
},
],
},
type: "array",
title: "Location",
},
msg: {
type: "string",
title: "Message",
},
type: {
type: "string",
title: "Error Type",
},
},
type: "object",
required: ["loc", "msg", "type"],
title: "ValidationError",
} as const;
export const $Word = {
properties: {
text: {
type: "string",
title: "Text",
},
start: {
type: "number",
title: "Start",
},
end: {
type: "number",
title: "End",
},
speaker: {
type: "integer",
title: "Speaker",
default: 0,
},
},
type: "object",
required: ["text", "start", "end"],
title: "Word",
} as const;

579
www/app/api/services.gen.ts Normal file
View File

@@ -0,0 +1,579 @@
// This file is auto-generated by @hey-api/openapi-ts
import type { CancelablePromise } from "./core/CancelablePromise";
import type { BaseHttpRequest } from "./core/BaseHttpRequest";
import type {
MetricsResponse,
V1TranscriptsListData,
V1TranscriptsListResponse,
V1TranscriptsCreateData,
V1TranscriptsCreateResponse,
V1TranscriptGetData,
V1TranscriptGetResponse,
V1TranscriptUpdateData,
V1TranscriptUpdateResponse,
V1TranscriptDeleteData,
V1TranscriptDeleteResponse,
V1TranscriptGetTopicsData,
V1TranscriptGetTopicsResponse,
V1TranscriptGetTopicsWithWordsData,
V1TranscriptGetTopicsWithWordsResponse,
V1TranscriptGetTopicsWithWordsPerSpeakerData,
V1TranscriptGetTopicsWithWordsPerSpeakerResponse,
V1TranscriptHeadAudioMp3Data,
V1TranscriptHeadAudioMp3Response,
V1TranscriptGetAudioMp3Data,
V1TranscriptGetAudioMp3Response,
V1TranscriptGetAudioWaveformData,
V1TranscriptGetAudioWaveformResponse,
V1TranscriptGetParticipantsData,
V1TranscriptGetParticipantsResponse,
V1TranscriptAddParticipantData,
V1TranscriptAddParticipantResponse,
V1TranscriptGetParticipantData,
V1TranscriptGetParticipantResponse,
V1TranscriptUpdateParticipantData,
V1TranscriptUpdateParticipantResponse,
V1TranscriptDeleteParticipantData,
V1TranscriptDeleteParticipantResponse,
V1TranscriptAssignSpeakerData,
V1TranscriptAssignSpeakerResponse,
V1TranscriptMergeSpeakerData,
V1TranscriptMergeSpeakerResponse,
V1TranscriptRecordUploadData,
V1TranscriptRecordUploadResponse,
V1TranscriptGetWebsocketEventsData,
V1TranscriptGetWebsocketEventsResponse,
V1TranscriptRecordWebrtcData,
V1TranscriptRecordWebrtcResponse,
V1UserMeResponse,
} from "./types.gen";
export class DefaultService {
constructor(public readonly httpRequest: BaseHttpRequest) {}
/**
* Metrics
* Endpoint that serves Prometheus metrics.
* @returns unknown Successful Response
* @throws ApiError
*/
public metrics(): CancelablePromise<MetricsResponse> {
return this.httpRequest.request({
method: "GET",
url: "/metrics",
});
}
/**
* Transcripts List
* @param data The data for the request.
* @param data.page Page number
* @param data.size Page size
* @returns Page_GetTranscript_ Successful Response
* @throws ApiError
*/
public v1TranscriptsList(
data: V1TranscriptsListData = {},
): CancelablePromise<V1TranscriptsListResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts",
query: {
page: data.page,
size: data.size,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcripts Create
* @param data The data for the request.
* @param data.requestBody
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptsCreate(
data: V1TranscriptsCreateData,
): CancelablePromise<V1TranscriptsCreateResponse> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts",
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get
* @param data The data for the request.
* @param data.transcriptId
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptGet(
data: V1TranscriptGetData,
): CancelablePromise<V1TranscriptGetResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Update
* @param data The data for the request.
* @param data.transcriptId
* @param data.requestBody
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptUpdate(
data: V1TranscriptUpdateData,
): CancelablePromise<V1TranscriptUpdateResponse> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: data.transcriptId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Delete
* @param data The data for the request.
* @param data.transcriptId
* @returns DeletionStatus Successful Response
* @throws ApiError
*/
public v1TranscriptDelete(
data: V1TranscriptDeleteData,
): CancelablePromise<V1TranscriptDeleteResponse> {
return this.httpRequest.request({
method: "DELETE",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Topics
* @param data The data for the request.
* @param data.transcriptId
* @returns GetTranscriptTopic Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopics(
data: V1TranscriptGetTopicsData,
): CancelablePromise<V1TranscriptGetTopicsResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Topics With Words
* @param data The data for the request.
* @param data.transcriptId
* @returns GetTranscriptTopicWithWords Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopicsWithWords(
data: V1TranscriptGetTopicsWithWordsData,
): CancelablePromise<V1TranscriptGetTopicsWithWordsResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics/with-words",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Topics With Words Per Speaker
* @param data The data for the request.
* @param data.transcriptId
* @param data.topicId
* @returns GetTranscriptTopicWithWordsPerSpeaker Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopicsWithWordsPerSpeaker(
data: V1TranscriptGetTopicsWithWordsPerSpeakerData,
): CancelablePromise<V1TranscriptGetTopicsWithWordsPerSpeakerResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics/{topic_id}/words-per-speaker",
path: {
transcript_id: data.transcriptId,
topic_id: data.topicId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Audio Mp3
* @param data The data for the request.
* @param data.transcriptId
* @param data.token
* @returns unknown Successful Response
* @throws ApiError
*/
public v1TranscriptHeadAudioMp3(
data: V1TranscriptHeadAudioMp3Data,
): CancelablePromise<V1TranscriptHeadAudioMp3Response> {
return this.httpRequest.request({
method: "HEAD",
url: "/v1/transcripts/{transcript_id}/audio/mp3",
path: {
transcript_id: data.transcriptId,
},
query: {
token: data.token,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Audio Mp3
* @param data The data for the request.
* @param data.transcriptId
* @param data.token
* @returns unknown Successful Response
* @throws ApiError
*/
public v1TranscriptGetAudioMp3(
data: V1TranscriptGetAudioMp3Data,
): CancelablePromise<V1TranscriptGetAudioMp3Response> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/audio/mp3",
path: {
transcript_id: data.transcriptId,
},
query: {
token: data.token,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Audio Waveform
* @param data The data for the request.
* @param data.transcriptId
* @returns AudioWaveform Successful Response
* @throws ApiError
*/
public v1TranscriptGetAudioWaveform(
data: V1TranscriptGetAudioWaveformData,
): CancelablePromise<V1TranscriptGetAudioWaveformResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/audio/waveform",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Participants
* @param data The data for the request.
* @param data.transcriptId
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptGetParticipants(
data: V1TranscriptGetParticipantsData,
): CancelablePromise<V1TranscriptGetParticipantsResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/participants",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Add Participant
* @param data The data for the request.
* @param data.transcriptId
* @param data.requestBody
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptAddParticipant(
data: V1TranscriptAddParticipantData,
): CancelablePromise<V1TranscriptAddParticipantResponse> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/participants",
path: {
transcript_id: data.transcriptId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Participant
* @param data The data for the request.
* @param data.transcriptId
* @param data.participantId
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptGetParticipant(
data: V1TranscriptGetParticipantData,
): CancelablePromise<V1TranscriptGetParticipantResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: data.transcriptId,
participant_id: data.participantId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Update Participant
* @param data The data for the request.
* @param data.transcriptId
* @param data.participantId
* @param data.requestBody
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptUpdateParticipant(
data: V1TranscriptUpdateParticipantData,
): CancelablePromise<V1TranscriptUpdateParticipantResponse> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: data.transcriptId,
participant_id: data.participantId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Delete Participant
* @param data The data for the request.
* @param data.transcriptId
* @param data.participantId
* @returns DeletionStatus Successful Response
* @throws ApiError
*/
public v1TranscriptDeleteParticipant(
data: V1TranscriptDeleteParticipantData,
): CancelablePromise<V1TranscriptDeleteParticipantResponse> {
return this.httpRequest.request({
method: "DELETE",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: data.transcriptId,
participant_id: data.participantId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Assign Speaker
* @param data The data for the request.
* @param data.transcriptId
* @param data.requestBody
* @returns SpeakerAssignmentStatus Successful Response
* @throws ApiError
*/
public v1TranscriptAssignSpeaker(
data: V1TranscriptAssignSpeakerData,
): CancelablePromise<V1TranscriptAssignSpeakerResponse> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/speaker/assign",
path: {
transcript_id: data.transcriptId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Merge Speaker
* @param data The data for the request.
* @param data.transcriptId
* @param data.requestBody
* @returns SpeakerAssignmentStatus Successful Response
* @throws ApiError
*/
public v1TranscriptMergeSpeaker(
data: V1TranscriptMergeSpeakerData,
): CancelablePromise<V1TranscriptMergeSpeakerResponse> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/speaker/merge",
path: {
transcript_id: data.transcriptId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Record Upload
* @param data The data for the request.
* @param data.transcriptId
* @param data.formData
* @returns unknown Successful Response
* @throws ApiError
*/
public v1TranscriptRecordUpload(
data: V1TranscriptRecordUploadData,
): CancelablePromise<V1TranscriptRecordUploadResponse> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/record/upload",
path: {
transcript_id: data.transcriptId,
},
formData: data.formData,
mediaType: "multipart/form-data",
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Get Websocket Events
* @param data The data for the request.
* @param data.transcriptId
* @returns unknown Successful Response
* @throws ApiError
*/
public v1TranscriptGetWebsocketEvents(
data: V1TranscriptGetWebsocketEventsData,
): CancelablePromise<V1TranscriptGetWebsocketEventsResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/events",
path: {
transcript_id: data.transcriptId,
},
errors: {
422: "Validation Error",
},
});
}
/**
* Transcript Record Webrtc
* @param data The data for the request.
* @param data.transcriptId
* @param data.requestBody
* @returns unknown Successful Response
* @throws ApiError
*/
public v1TranscriptRecordWebrtc(
data: V1TranscriptRecordWebrtcData,
): CancelablePromise<V1TranscriptRecordWebrtcResponse> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/record/webrtc",
path: {
transcript_id: data.transcriptId,
},
body: data.requestBody,
mediaType: "application/json",
errors: {
422: "Validation Error",
},
});
}
/**
* User Me
* @returns unknown Successful Response
* @throws ApiError
*/
public v1UserMe(): CancelablePromise<V1UserMeResponse> {
return this.httpRequest.request({
method: "GET",
url: "/v1/me",
});
}
}

View File

@@ -1,547 +0,0 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { AudioWaveform } from "../models/AudioWaveform";
import type { Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post } from "../models/Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post";
import type { CreateParticipant } from "../models/CreateParticipant";
import type { CreateTranscript } from "../models/CreateTranscript";
import type { DeletionStatus } from "../models/DeletionStatus";
import type { GetTranscript } from "../models/GetTranscript";
import type { GetTranscriptTopic } from "../models/GetTranscriptTopic";
import type { GetTranscriptTopicWithWords } from "../models/GetTranscriptTopicWithWords";
import type { GetTranscriptTopicWithWordsPerSpeaker } from "../models/GetTranscriptTopicWithWordsPerSpeaker";
import type { Page_GetTranscript_ } from "../models/Page_GetTranscript_";
import type { Participant } from "../models/Participant";
import type { RtcOffer } from "../models/RtcOffer";
import type { SpeakerAssignment } from "../models/SpeakerAssignment";
import type { SpeakerAssignmentStatus } from "../models/SpeakerAssignmentStatus";
import type { SpeakerMerge } from "../models/SpeakerMerge";
import type { UpdateParticipant } from "../models/UpdateParticipant";
import type { UpdateTranscript } from "../models/UpdateTranscript";
import type { UserInfo } from "../models/UserInfo";
import type { CancelablePromise } from "../core/CancelablePromise";
import type { BaseHttpRequest } from "../core/BaseHttpRequest";
export class DefaultService {
constructor(public readonly httpRequest: BaseHttpRequest) {}
/**
* Metrics
* Endpoint that serves Prometheus metrics.
* @returns any Successful Response
* @throws ApiError
*/
public metrics(): CancelablePromise<any> {
return this.httpRequest.request({
method: "GET",
url: "/metrics",
});
}
/**
* Transcripts List
* @param page Page number
* @param size Page size
* @returns Page_GetTranscript_ Successful Response
* @throws ApiError
*/
public v1TranscriptsList(
page: number = 1,
size: number = 50,
): CancelablePromise<Page_GetTranscript_> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts",
query: {
page: page,
size: size,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcripts Create
* @param requestBody
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptsCreate(
requestBody: CreateTranscript,
): CancelablePromise<GetTranscript> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts",
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get
* @param transcriptId
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptGet(
transcriptId: string,
): CancelablePromise<GetTranscript> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Update
* @param transcriptId
* @param requestBody
* @returns GetTranscript Successful Response
* @throws ApiError
*/
public v1TranscriptUpdate(
transcriptId: string,
requestBody: UpdateTranscript,
): CancelablePromise<GetTranscript> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: transcriptId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Delete
* @param transcriptId
* @returns DeletionStatus Successful Response
* @throws ApiError
*/
public v1TranscriptDelete(
transcriptId: string,
): CancelablePromise<DeletionStatus> {
return this.httpRequest.request({
method: "DELETE",
url: "/v1/transcripts/{transcript_id}",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Topics
* @param transcriptId
* @returns GetTranscriptTopic Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopics(
transcriptId: string,
): CancelablePromise<Array<GetTranscriptTopic>> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Topics With Words
* @param transcriptId
* @returns GetTranscriptTopicWithWords Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopicsWithWords(
transcriptId: string,
): CancelablePromise<Array<GetTranscriptTopicWithWords>> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics/with-words",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Topics With Words Per Speaker
* @param transcriptId
* @param topicId
* @returns GetTranscriptTopicWithWordsPerSpeaker Successful Response
* @throws ApiError
*/
public v1TranscriptGetTopicsWithWordsPerSpeaker(
transcriptId: string,
topicId: string,
): CancelablePromise<GetTranscriptTopicWithWordsPerSpeaker> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/topics/{topic_id}/words-per-speaker",
path: {
transcript_id: transcriptId,
topic_id: topicId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Audio Mp3
* @param transcriptId
* @param token
* @returns any Successful Response
* @throws ApiError
*/
public v1TranscriptHeadAudioMp3(
transcriptId: string,
token?: string | null,
): CancelablePromise<any> {
return this.httpRequest.request({
method: "HEAD",
url: "/v1/transcripts/{transcript_id}/audio/mp3",
path: {
transcript_id: transcriptId,
},
query: {
token: token,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Audio Mp3
* @param transcriptId
* @param token
* @returns any Successful Response
* @throws ApiError
*/
public v1TranscriptGetAudioMp3(
transcriptId: string,
token?: string | null,
): CancelablePromise<any> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/audio/mp3",
path: {
transcript_id: transcriptId,
},
query: {
token: token,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Audio Waveform
* @param transcriptId
* @returns AudioWaveform Successful Response
* @throws ApiError
*/
public v1TranscriptGetAudioWaveform(
transcriptId: string,
): CancelablePromise<AudioWaveform> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/audio/waveform",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Participants
* @param transcriptId
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptGetParticipants(
transcriptId: string,
): CancelablePromise<Array<Participant>> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/participants",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Add Participant
* @param transcriptId
* @param requestBody
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptAddParticipant(
transcriptId: string,
requestBody: CreateParticipant,
): CancelablePromise<Participant> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/participants",
path: {
transcript_id: transcriptId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Participant
* @param transcriptId
* @param participantId
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptGetParticipant(
transcriptId: string,
participantId: string,
): CancelablePromise<Participant> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: transcriptId,
participant_id: participantId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Update Participant
* @param transcriptId
* @param participantId
* @param requestBody
* @returns Participant Successful Response
* @throws ApiError
*/
public v1TranscriptUpdateParticipant(
transcriptId: string,
participantId: string,
requestBody: UpdateParticipant,
): CancelablePromise<Participant> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: transcriptId,
participant_id: participantId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Delete Participant
* @param transcriptId
* @param participantId
* @returns DeletionStatus Successful Response
* @throws ApiError
*/
public v1TranscriptDeleteParticipant(
transcriptId: string,
participantId: string,
): CancelablePromise<DeletionStatus> {
return this.httpRequest.request({
method: "DELETE",
url: "/v1/transcripts/{transcript_id}/participants/{participant_id}",
path: {
transcript_id: transcriptId,
participant_id: participantId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Assign Speaker
* @param transcriptId
* @param requestBody
* @returns SpeakerAssignmentStatus Successful Response
* @throws ApiError
*/
public v1TranscriptAssignSpeaker(
transcriptId: string,
requestBody: SpeakerAssignment,
): CancelablePromise<SpeakerAssignmentStatus> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/speaker/assign",
path: {
transcript_id: transcriptId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Merge Speaker
* @param transcriptId
* @param requestBody
* @returns SpeakerAssignmentStatus Successful Response
* @throws ApiError
*/
public v1TranscriptMergeSpeaker(
transcriptId: string,
requestBody: SpeakerMerge,
): CancelablePromise<SpeakerAssignmentStatus> {
return this.httpRequest.request({
method: "PATCH",
url: "/v1/transcripts/{transcript_id}/speaker/merge",
path: {
transcript_id: transcriptId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Record Upload
* @param transcriptId
* @param formData
* @returns any Successful Response
* @throws ApiError
*/
public v1TranscriptRecordUpload(
transcriptId: string,
formData: Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post,
): CancelablePromise<any> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/record/upload",
path: {
transcript_id: transcriptId,
},
formData: formData,
mediaType: "multipart/form-data",
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Get Websocket Events
* @param transcriptId
* @returns any Successful Response
* @throws ApiError
*/
public v1TranscriptGetWebsocketEvents(
transcriptId: string,
): CancelablePromise<any> {
return this.httpRequest.request({
method: "GET",
url: "/v1/transcripts/{transcript_id}/events",
path: {
transcript_id: transcriptId,
},
errors: {
422: `Validation Error`,
},
});
}
/**
* Transcript Record Webrtc
* @param transcriptId
* @param requestBody
* @returns any Successful Response
* @throws ApiError
*/
public v1TranscriptRecordWebrtc(
transcriptId: string,
requestBody: RtcOffer,
): CancelablePromise<any> {
return this.httpRequest.request({
method: "POST",
url: "/v1/transcripts/{transcript_id}/record/webrtc",
path: {
transcript_id: transcriptId,
},
body: requestBody,
mediaType: "application/json",
errors: {
422: `Validation Error`,
},
});
}
/**
* User Me
* @returns any Successful Response
* @throws ApiError
*/
public v1UserMe(): CancelablePromise<UserInfo | null> {
return this.httpRequest.request({
method: "GET",
url: "/v1/me",
});
}
}

642
www/app/api/types.gen.ts Normal file
View File

@@ -0,0 +1,642 @@
// This file is auto-generated by @hey-api/openapi-ts
export type AudioWaveform = {
data: Array<number>;
};
export type Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post =
{
file: Blob | File;
};
export type CreateParticipant = {
speaker?: number | null;
name: string;
};
export type CreateTranscript = {
name: string;
source_language?: string;
target_language?: string;
};
export type DeletionStatus = {
status: string;
};
export type GetTranscript = {
id: string;
user_id: string | null;
name: string;
status: string;
locked: boolean;
duration: number;
title: string | null;
short_summary: string | null;
long_summary: string | null;
created_at: string;
share_mode?: string;
source_language: string | null;
target_language: string | null;
participants: Array<TranscriptParticipant> | null;
reviewed: boolean;
};
export type GetTranscriptSegmentTopic = {
text: string;
start: number;
speaker: number;
};
export type GetTranscriptTopic = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
};
export type GetTranscriptTopicWithWords = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
words?: Array<Word>;
};
export type GetTranscriptTopicWithWordsPerSpeaker = {
id: string;
title: string;
summary: string;
timestamp: number;
duration: number | null;
transcript: string;
segments?: Array<GetTranscriptSegmentTopic>;
words_per_speaker?: Array<SpeakerWords>;
};
export type HTTPValidationError = {
detail?: Array<ValidationError>;
};
export type Page_GetTranscript_ = {
items: Array<GetTranscript>;
total: number;
page: number | null;
size: number | null;
pages?: number | null;
};
export type Participant = {
id: string;
speaker: number | null;
name: string;
};
export type RtcOffer = {
sdp: string;
type: string;
};
export type SpeakerAssignment = {
speaker?: number | null;
participant?: string | null;
timestamp_from: number;
timestamp_to: number;
};
export type SpeakerAssignmentStatus = {
status: string;
};
export type SpeakerMerge = {
speaker_from: number;
speaker_to: number;
};
export type SpeakerWords = {
speaker: number;
words: Array<Word>;
};
export type TranscriptParticipant = {
id?: string;
speaker: number | null;
name: string;
};
export type UpdateParticipant = {
speaker?: number | null;
name?: string | null;
};
export type UpdateTranscript = {
name?: string | null;
locked?: boolean | null;
title?: string | null;
short_summary?: string | null;
long_summary?: string | null;
share_mode?: "public" | "semi-private" | "private" | null;
participants?: Array<TranscriptParticipant> | null;
reviewed?: boolean | null;
};
export type UserInfo = {
sub: string;
email: string | null;
email_verified: boolean | null;
};
export type ValidationError = {
loc: Array<string | number>;
msg: string;
type: string;
};
export type Word = {
text: string;
start: number;
end: number;
speaker?: number;
};
export type MetricsResponse = unknown;
export type V1TranscriptsListData = {
/**
* Page number
*/
page?: number;
/**
* Page size
*/
size?: number;
};
export type V1TranscriptsListResponse = Page_GetTranscript_;
export type V1TranscriptsCreateData = {
requestBody: CreateTranscript;
};
export type V1TranscriptsCreateResponse = GetTranscript;
export type V1TranscriptGetData = {
transcriptId: string;
};
export type V1TranscriptGetResponse = GetTranscript;
export type V1TranscriptUpdateData = {
requestBody: UpdateTranscript;
transcriptId: string;
};
export type V1TranscriptUpdateResponse = GetTranscript;
export type V1TranscriptDeleteData = {
transcriptId: string;
};
export type V1TranscriptDeleteResponse = DeletionStatus;
export type V1TranscriptGetTopicsData = {
transcriptId: string;
};
export type V1TranscriptGetTopicsResponse = Array<GetTranscriptTopic>;
export type V1TranscriptGetTopicsWithWordsData = {
transcriptId: string;
};
export type V1TranscriptGetTopicsWithWordsResponse =
Array<GetTranscriptTopicWithWords>;
export type V1TranscriptGetTopicsWithWordsPerSpeakerData = {
topicId: string;
transcriptId: string;
};
export type V1TranscriptGetTopicsWithWordsPerSpeakerResponse =
GetTranscriptTopicWithWordsPerSpeaker;
export type V1TranscriptHeadAudioMp3Data = {
token?: string | null;
transcriptId: string;
};
export type V1TranscriptHeadAudioMp3Response = unknown;
export type V1TranscriptGetAudioMp3Data = {
token?: string | null;
transcriptId: string;
};
export type V1TranscriptGetAudioMp3Response = unknown;
export type V1TranscriptGetAudioWaveformData = {
transcriptId: string;
};
export type V1TranscriptGetAudioWaveformResponse = AudioWaveform;
export type V1TranscriptGetParticipantsData = {
transcriptId: string;
};
export type V1TranscriptGetParticipantsResponse = Array<Participant>;
export type V1TranscriptAddParticipantData = {
requestBody: CreateParticipant;
transcriptId: string;
};
export type V1TranscriptAddParticipantResponse = Participant;
export type V1TranscriptGetParticipantData = {
participantId: string;
transcriptId: string;
};
export type V1TranscriptGetParticipantResponse = Participant;
export type V1TranscriptUpdateParticipantData = {
participantId: string;
requestBody: UpdateParticipant;
transcriptId: string;
};
export type V1TranscriptUpdateParticipantResponse = Participant;
export type V1TranscriptDeleteParticipantData = {
participantId: string;
transcriptId: string;
};
export type V1TranscriptDeleteParticipantResponse = DeletionStatus;
export type V1TranscriptAssignSpeakerData = {
requestBody: SpeakerAssignment;
transcriptId: string;
};
export type V1TranscriptAssignSpeakerResponse = SpeakerAssignmentStatus;
export type V1TranscriptMergeSpeakerData = {
requestBody: SpeakerMerge;
transcriptId: string;
};
export type V1TranscriptMergeSpeakerResponse = SpeakerAssignmentStatus;
export type V1TranscriptRecordUploadData = {
formData: Body_transcript_record_upload_v1_transcripts__transcript_id__record_upload_post;
transcriptId: string;
};
export type V1TranscriptRecordUploadResponse = unknown;
export type V1TranscriptGetWebsocketEventsData = {
transcriptId: string;
};
export type V1TranscriptGetWebsocketEventsResponse = unknown;
export type V1TranscriptRecordWebrtcData = {
requestBody: RtcOffer;
transcriptId: string;
};
export type V1TranscriptRecordWebrtcResponse = unknown;
export type V1UserMeResponse = UserInfo | null;
export type $OpenApiTs = {
"/metrics": {
get: {
res: {
/**
* Successful Response
*/
200: unknown;
};
};
};
"/v1/transcripts": {
get: {
req: V1TranscriptsListData;
res: {
/**
* Successful Response
*/
200: Page_GetTranscript_;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
post: {
req: V1TranscriptsCreateData;
res: {
/**
* Successful Response
*/
200: GetTranscript;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}": {
get: {
req: V1TranscriptGetData;
res: {
/**
* Successful Response
*/
200: GetTranscript;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
patch: {
req: V1TranscriptUpdateData;
res: {
/**
* Successful Response
*/
200: GetTranscript;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
delete: {
req: V1TranscriptDeleteData;
res: {
/**
* Successful Response
*/
200: DeletionStatus;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/topics": {
get: {
req: V1TranscriptGetTopicsData;
res: {
/**
* Successful Response
*/
200: Array<GetTranscriptTopic>;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/topics/with-words": {
get: {
req: V1TranscriptGetTopicsWithWordsData;
res: {
/**
* Successful Response
*/
200: Array<GetTranscriptTopicWithWords>;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/topics/{topic_id}/words-per-speaker": {
get: {
req: V1TranscriptGetTopicsWithWordsPerSpeakerData;
res: {
/**
* Successful Response
*/
200: GetTranscriptTopicWithWordsPerSpeaker;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/audio/mp3": {
head: {
req: V1TranscriptHeadAudioMp3Data;
res: {
/**
* Successful Response
*/
200: unknown;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
get: {
req: V1TranscriptGetAudioMp3Data;
res: {
/**
* Successful Response
*/
200: unknown;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/audio/waveform": {
get: {
req: V1TranscriptGetAudioWaveformData;
res: {
/**
* Successful Response
*/
200: AudioWaveform;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/participants": {
get: {
req: V1TranscriptGetParticipantsData;
res: {
/**
* Successful Response
*/
200: Array<Participant>;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
post: {
req: V1TranscriptAddParticipantData;
res: {
/**
* Successful Response
*/
200: Participant;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/participants/{participant_id}": {
get: {
req: V1TranscriptGetParticipantData;
res: {
/**
* Successful Response
*/
200: Participant;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
patch: {
req: V1TranscriptUpdateParticipantData;
res: {
/**
* Successful Response
*/
200: Participant;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
delete: {
req: V1TranscriptDeleteParticipantData;
res: {
/**
* Successful Response
*/
200: DeletionStatus;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/speaker/assign": {
patch: {
req: V1TranscriptAssignSpeakerData;
res: {
/**
* Successful Response
*/
200: SpeakerAssignmentStatus;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/speaker/merge": {
patch: {
req: V1TranscriptMergeSpeakerData;
res: {
/**
* Successful Response
*/
200: SpeakerAssignmentStatus;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/record/upload": {
post: {
req: V1TranscriptRecordUploadData;
res: {
/**
* Successful Response
*/
200: unknown;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/events": {
get: {
req: V1TranscriptGetWebsocketEventsData;
res: {
/**
* Successful Response
*/
200: unknown;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/transcripts/{transcript_id}/record/webrtc": {
post: {
req: V1TranscriptRecordWebrtcData;
res: {
/**
* Successful Response
*/
200: unknown;
/**
* Validation Error
*/
422: HTTPValidationError;
};
};
};
"/v1/me": {
get: {
res: {
/**
* Successful Response
*/
200: UserInfo | null;
};
};
};
};

View File

@@ -5,7 +5,7 @@ import { extractDomain } from "./utils";
export async function sendZulipMessage(
stream: string,
topic: string,
message: string
message: string,
) {
console.log("Sendiing zulip message", stream, topic);
try {
@@ -28,14 +28,14 @@ export const ZULIP_MSG_MAX_LENGTH = 10000;
export function getZulipMessage(
transcript: GetTranscript,
topics: GetTranscriptTopic[] | null,
includeTopics: boolean
includeTopics: boolean,
) {
const date = new Date(transcript.created_at);
// Get the timezone offset in minutes and convert it to hours and minutes
const timezoneOffset = -date.getTimezoneOffset();
const offsetHours = String(
Math.floor(Math.abs(timezoneOffset) / 60)
Math.floor(Math.abs(timezoneOffset) / 60),
).padStart(2, "0");
const offsetMinutes = String(Math.abs(timezoneOffset) % 60).padStart(2, "0");
const offsetSign = timezoneOffset >= 0 ? "+" : "-";

14
www/openapi-ts.config.ts Normal file
View File

@@ -0,0 +1,14 @@
import { defineConfig } from "@hey-api/openapi-ts";
export default defineConfig({
client: "axios",
name: "OpenApi",
input: "http://127.0.0.1:1250/openapi.json",
output: {
path: "./app/api",
format: "prettier",
},
services: {
asClass: true,
},
});

View File

@@ -8,7 +8,7 @@
"start": "next start",
"lint": "next lint",
"format": "prettier --write .",
"openapi": "openapi --input http://127.0.0.1:1250/openapi.json --name OpenApi --output app/api && yarn format"
"openapi": "openapi-ts"
},
"dependencies": {
"@chakra-ui/icons": "^2.1.1",
@@ -55,9 +55,8 @@
"author": "Andreas <andreas@monadical.com>",
"license": "All Rights Reserved",
"devDependencies": {
"@openapitools/openapi-generator-cli": "^2.7.0",
"@types/react": "18.2.20",
"openapi-typescript-codegen": "^0.25.0",
"@hey-api/openapi-ts": "^0.48.0",
"prettier": "^3.0.0"
}
}

File diff suppressed because it is too large Load Diff