diff --git a/website/src/components/FlaggableElement.tsx b/website/src/components/FlaggableElement.tsx index 79431fc5..f2f3242b 100644 --- a/website/src/components/FlaggableElement.tsx +++ b/website/src/components/FlaggableElement.tsx @@ -23,8 +23,7 @@ import { } from "@chakra-ui/react"; import { FlagIcon, QuestionMarkCircleIcon } from "@heroicons/react/20/solid"; import { useEffect, useReducer } from "react"; -import fetcher from "src/lib/fetcher"; -import poster from "src/lib/poster"; +import { get, post } from "src/lib/api"; import { Message } from "src/types/Conversation"; import { colors } from "styles/Theme/colors"; import useSWR from "swr"; @@ -101,7 +100,7 @@ export const FlaggableElement = (props: FlaggableElementProps) => { const [isEditing, setIsEditing] = useBoolean(); const backgroundColor = useColorModeValue("gray.200", "gray.700"); - const { data, isLoading } = useSWR("/api/valid_labels", fetcher); + const { data, isLoading } = useSWR("/api/valid_labels", get); useEffect(() => { if (isLoading) { return; @@ -110,7 +109,7 @@ export const FlaggableElement = (props: FlaggableElementProps) => { updateReport({ type: "load_labels", labels: valid_labels }); }, [data, isLoading]); - const { trigger } = useSWRMutation("/api/set_label", poster, { + const { trigger } = useSWRMutation("/api/set_label", post, { onSuccess: () => { setIsEditing.off(); }, diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index d29021dc..d7b8b08c 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -12,7 +12,6 @@ interface MessageTableEntryProps { export function MessageTableEntry(props: MessageTableEntryProps) { const { item } = props; const backgroundColor = useColorModeValue("gray.50", "gray.800"); - return (
diff --git a/website/src/components/Messages/MessageWithChildren.tsx b/website/src/components/Messages/MessageWithChildren.tsx index 156020ec..39b6bbbd 100644 --- a/website/src/components/Messages/MessageWithChildren.tsx +++ b/website/src/components/Messages/MessageWithChildren.tsx @@ -2,7 +2,7 @@ import { Box, CircularProgress, Stack, StackProps, Text, TextProps, useColorMode import { boolean } from "boolean"; import { useState } from "react"; import { MessageTableEntry } from "src/components/Messages/MessageTableEntry"; -import fetcher from "src/lib/fetcher"; +import { get } from "src/lib/api"; import useSWR from "swr"; const MessageHeaderProps: TextProps = { @@ -34,7 +34,7 @@ export function MessageWithChildren(props: MessageWithChildrenProps) { const [message, setMessage] = useState(null); const [children, setChildren] = useState(null); - const { isLoading } = useSWR(id ? `/api/messages/${id}` : null, fetcher, { + const { isLoading } = useSWR(id ? `/api/messages/${id}` : null, get, { onSuccess: (data) => { setMessage(data); }, @@ -42,7 +42,7 @@ export function MessageWithChildren(props: MessageWithChildrenProps) { setMessage(null); }, }); - const { isLoading: isLoadingChildren } = useSWR(id ? `/api/messages/${id}/children` : null, fetcher, { + const { isLoading: isLoadingChildren } = useSWR(id ? `/api/messages/${id}/children` : null, get, { onSuccess: (data) => { setChildren(data); }, diff --git a/website/src/components/Tasks/Task.tsx b/website/src/components/Tasks/Task.tsx index 24a95d78..ee395235 100644 --- a/website/src/components/Tasks/Task.tsx +++ b/website/src/components/Tasks/Task.tsx @@ -5,7 +5,7 @@ import { EvaluateTask } from "src/components/Tasks/EvaluateTask"; import { LabelTask } from "src/components/Tasks/LabelTask"; import { TaskCategory, TaskInfo, TaskTypes } from "src/components/Tasks/TaskTypes"; import { UnchangedWarning } from "src/components/Tasks/UnchangedWarning"; -import poster from "src/lib/poster"; +import { post } from "src/lib/api"; import { TaskContent } from "src/types/Task"; import { TaskReplyState } from "src/types/TaskReplyState"; import useSWRMutation from "swr/mutation"; @@ -28,7 +28,7 @@ export const Task = ({ frontendId, task, trigger, mutate }) => { const taskType = TaskTypes.find((taskType) => taskType.type === task.type); - const { trigger: sendRejection } = useSWRMutation("/api/reject_task", poster, { + const { trigger: sendRejection } = useSWRMutation("/api/reject_task", post, { onSuccess: async () => { mutate(); }, diff --git a/website/src/components/UserMessagesCell/UserMessagesCell.tsx b/website/src/components/UserMessagesCell/UserMessagesCell.tsx index 39120242..4f3a454e 100644 --- a/website/src/components/UserMessagesCell/UserMessagesCell.tsx +++ b/website/src/components/UserMessagesCell/UserMessagesCell.tsx @@ -1,6 +1,6 @@ import { Box, CircularProgress, useColorModeValue } from "@chakra-ui/react"; import { MessageTable } from "src/components/Messages/MessageTable"; -import fetcher from "src/lib/fetcher"; +import { get } from "src/lib/api"; import useSWR from "swr"; interface UserMessagesCellProps { @@ -16,7 +16,7 @@ interface UserMessagesCellProps { */ const UserMessagesCell = ({ path }: UserMessagesCellProps) => { const url = path || "/api/messages/user"; - const { data: messages, isLoading } = useSWR(url, fetcher, { + const { data: messages, isLoading } = useSWR(url, get, { refreshInterval: 2000, }); // TODO(#651): This box coloring and styling is used in multiple places. We diff --git a/website/src/components/UsersCell.tsx b/website/src/components/UsersCell.tsx index 5354ee5c..63c923a7 100644 --- a/website/src/components/UsersCell.tsx +++ b/website/src/components/UsersCell.tsx @@ -14,7 +14,7 @@ import { } from "@chakra-ui/react"; import Link from "next/link"; import { useState } from "react"; -import fetcher from "src/lib/fetcher"; +import { get } from "src/lib/api"; import useSWR from "swr"; /** @@ -27,7 +27,7 @@ const UsersCell = () => { // Fetch and save the users. // This follows useSWR's recommendation for simple pagination: // https://swr.vercel.app/docs/pagination#when-to-use-useswr - useSWR(`/api/admin/users?pageIndex=${pageIndex}`, fetcher, { + useSWR(`/api/admin/users?pageIndex=${pageIndex}`, get, { onSuccess: setUsers, }); diff --git a/website/src/hooks/tasks/useGenericTaskAPI.tsx b/website/src/hooks/tasks/useGenericTaskAPI.tsx index 52ab6a7f..e8f490ae 100644 --- a/website/src/hooks/tasks/useGenericTaskAPI.tsx +++ b/website/src/hooks/tasks/useGenericTaskAPI.tsx @@ -1,6 +1,5 @@ import { useState } from "react"; -import fetcher from "src/lib/fetcher"; -import poster from "src/lib/poster"; +import { get, post } from "src/lib/api"; import { BaseTask, TaskResponse } from "src/types/Task"; import useSWRImmutable from "swr/immutable"; import useSWRMutation from "swr/mutation"; @@ -10,19 +9,15 @@ export const useGenericTaskAPI = (taskApiEndpoint: st const [tasks, setTasks] = useState([]); - const { isLoading, mutate, error } = useSWRImmutable( - "/api/new_task/" + taskApiEndpoint, - fetcher, - { - onSuccess: (data) => setTasks([data]), - revalidateOnMount: true, - dedupingInterval: 500, - } - ); + const { isLoading, mutate, error } = useSWRImmutable("/api/new_task/" + taskApiEndpoint, get, { + onSuccess: (data) => setTasks([data]), + revalidateOnMount: true, + dedupingInterval: 500, + }); - const { trigger } = useSWRMutation("/api/update_task", poster, { + const { trigger } = useSWRMutation("/api/update_task", post, { onSuccess: async (response) => { - const newTask: ConcreteTaskResponse = await response.json(); + const newTask: ConcreteTaskResponse = response; setTasks((oldTasks) => [...oldTasks, newTask]); mutate(); }, diff --git a/website/src/lib/api.ts b/website/src/lib/api.ts new file mode 100644 index 00000000..df4bd399 --- /dev/null +++ b/website/src/lib/api.ts @@ -0,0 +1,24 @@ +import axios from "axios"; + +import { OasstError } from "./oasst_api_client"; + +const headers = { + "Content-Type": "application/json", +}; + +const api = axios.create({ + headers, +}); + +export const get = (url: string) => api.get(url).then((res) => res.data); + +export const post = (url: string, { arg: data }) => api.post(url, data).then((res) => res.data); + +api.interceptors.response.use( + (response) => response, + (error) => { + throw new OasstError(error.message ?? error, error.error_code); + } +); + +export default api; diff --git a/website/src/lib/fetcher.ts b/website/src/lib/fetcher.ts deleted file mode 100644 index 3daa92a1..00000000 --- a/website/src/lib/fetcher.ts +++ /dev/null @@ -1,8 +0,0 @@ -import axios from "axios"; - -/** - * A minimal Axios based fetcher. - */ -const fetcher = (url) => axios.get(url).then((res) => res.data); - -export default fetcher; diff --git a/website/src/lib/oasst_api_client.ts b/website/src/lib/oasst_api_client.ts index 670640ad..381e6e0f 100644 --- a/website/src/lib/oasst_api_client.ts +++ b/website/src/lib/oasst_api_client.ts @@ -5,7 +5,7 @@ export class OasstError { errorCode: number; httpStatusCode: number; - constructor(message: string, errorCode: number, httpStatusCode: number) { + constructor(message: string, errorCode: number, httpStatusCode?: number) { this.message = message; this.errorCode = errorCode; this.httpStatusCode = httpStatusCode; diff --git a/website/src/lib/poster.ts b/website/src/lib/poster.ts deleted file mode 100644 index 9d961806..00000000 --- a/website/src/lib/poster.ts +++ /dev/null @@ -1,8 +0,0 @@ -const poster = (url, { arg }) => { - return fetch(url, { - method: "POST", - body: JSON.stringify(arg), - }); -}; - -export default poster; diff --git a/website/src/pages/admin/manage_user/[id].tsx b/website/src/pages/admin/manage_user/[id].tsx index fb2a3b74..6386c155 100644 --- a/website/src/pages/admin/manage_user/[id].tsx +++ b/website/src/pages/admin/manage_user/[id].tsx @@ -6,7 +6,7 @@ import { useSession } from "next-auth/react"; import { useEffect } from "react"; import { getAdminLayout } from "src/components/Layout"; import { UserMessagesCell } from "src/components/UserMessagesCell"; -import poster from "src/lib/poster"; +import { post } from "src/lib/api"; import prisma from "src/lib/prismadb"; import useSWRMutation from "swr/mutation"; @@ -31,7 +31,7 @@ const ManageUser = ({ user }) => { }, [router, session, status]); // Trigger to let us update the user's role. Triggers a toast when complete. - const { trigger } = useSWRMutation("/api/admin/update_user", poster, { + const { trigger } = useSWRMutation("/api/admin/update_user", post, { onSuccess: () => { toast({ title: "User Role Updated", diff --git a/website/src/pages/api/admin/update_user.ts b/website/src/pages/api/admin/update_user.ts index 3a309b7e..95ddff4b 100644 --- a/website/src/pages/api/admin/update_user.ts +++ b/website/src/pages/api/admin/update_user.ts @@ -5,7 +5,7 @@ import prisma from "src/lib/prismadb"; * Update's the user's data in the database. Accessible only to admins. */ const handler = withRole("admin", async (req, res) => { - const { id, role } = JSON.parse(req.body); + const { id, role } = req.body; await prisma.user.update({ where: { diff --git a/website/src/pages/api/reject_task.ts b/website/src/pages/api/reject_task.ts index d5185827..0084fffa 100644 --- a/website/src/pages/api/reject_task.ts +++ b/website/src/pages/api/reject_task.ts @@ -5,7 +5,7 @@ import prisma from "src/lib/prismadb"; const handler = withoutRole("banned", async (req, res) => { // Parse out the local task ID and the interaction contents. - const { id: frontendId, reason } = await JSON.parse(req.body); + const { id: frontendId, reason } = req.body; const registeredTask = await prisma.registeredTask.findUniqueOrThrow({ where: { id: frontendId } }); diff --git a/website/src/pages/api/set_label.ts b/website/src/pages/api/set_label.ts index 7d7b2d2e..93a150d5 100644 --- a/website/src/pages/api/set_label.ts +++ b/website/src/pages/api/set_label.ts @@ -6,8 +6,7 @@ import { withoutRole } from "src/lib/auth"; */ const handler = withoutRole("banned", async (req, res, token) => { // Parse out the local message_id, and the interaction contents. - const { message_id, label_map, text } = await JSON.parse(req.body); - + const { message_id, label_map, text } = req.body; const interactionRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/text_labels`, { method: "POST", headers: { diff --git a/website/src/pages/api/update_task.ts b/website/src/pages/api/update_task.ts index 96808820..f3aa6fb1 100644 --- a/website/src/pages/api/update_task.ts +++ b/website/src/pages/api/update_task.ts @@ -15,7 +15,7 @@ import prisma from "src/lib/prismadb"; */ const handler = withoutRole("banned", async (req, res, token) => { // Parse out the local task ID and the interaction contents. - const { id: frontendId, content, update_type } = await JSON.parse(req.body); + const { id: frontendId, content, update_type } = req.body; // Accept the task so that we can complete it, this will probably go away soon. const registeredTask = await prisma.registeredTask.findUniqueOrThrow({ where: { id: frontendId } }); diff --git a/website/src/pages/messages/[id]/index.tsx b/website/src/pages/messages/[id]/index.tsx index 9493907c..c1712b6d 100644 --- a/website/src/pages/messages/[id]/index.tsx +++ b/website/src/pages/messages/[id]/index.tsx @@ -5,14 +5,14 @@ import { getDashboardLayout } from "src/components/Layout"; import { MessageLoading } from "src/components/Loading/MessageLoading"; import { MessageTableEntry } from "src/components/Messages/MessageTableEntry"; import { MessageWithChildren } from "src/components/Messages/MessageWithChildren"; -import fetcher from "src/lib/fetcher"; +import { get } from "src/lib/api"; import useSWR from "swr"; const MessageDetail = ({ id }) => { const backgroundColor = useColorModeValue("white", "gray.700"); const [parent, setParent] = useState(null); - const { isLoading: isLoadingParent } = useSWR(id ? `/api/messages/${id}/parent` : null, fetcher, { + const { isLoading: isLoadingParent } = useSWR(id ? `/api/messages/${id}/parent` : null, get, { onSuccess: (data) => { setParent(data); }, diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index 04ef1ba4..1da42db4 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -3,7 +3,7 @@ import Head from "next/head"; import { useEffect, useState } from "react"; import { getDashboardLayout } from "src/components/Layout"; import { MessageTable } from "src/components/Messages/MessageTable"; -import fetcher from "src/lib/fetcher"; +import { get } from "src/lib/api"; import { Message } from "src/types/Conversation"; import useSWRImmutable from "swr/immutable"; @@ -14,11 +14,11 @@ const MessagesDashboard = () => { const [messages, setMessages] = useState(null); const [userMessages, setUserMessages] = useState(null); - const { isLoading: isLoadingAll, mutate: mutateAll } = useSWRImmutable("/api/messages", fetcher, { + const { isLoading: isLoadingAll, mutate: mutateAll } = useSWRImmutable("/api/messages", get, { onSuccess: setMessages, }); - const { isLoading: isLoadingUser, mutate: mutateUser } = useSWRImmutable(`/api/messages/user`, fetcher, { + const { isLoading: isLoadingUser, mutate: mutateUser } = useSWRImmutable(`/api/messages/user`, get, { onSuccess: setUserMessages, });