fix building by adjusting types

This commit is contained in:
Max Leiter 2023-02-26 15:21:43 -08:00
parent 6cf544fc72
commit 27a604dc90
10 changed files with 70 additions and 45 deletions

View file

@ -44,7 +44,12 @@ const PasswordModalWrapper = ({ setPost, postId, authorId }: Props) => {
return return
} }
const data = await res.json() // TODO: properly check type
const data = (await res.json()) as {
post: PostWithFilesAndAuthor
error?: string
}
if (data) { if (data) {
if (data.error) { if (data.error) {
setToast({ setToast({

View file

@ -18,17 +18,30 @@ export function Providers({ children }: PropsWithChildren<unknown>) {
) )
} }
export type ApiResponse<T> = {
data: T
error: never
} | {
data: never
error: string
}
async function fetcher<T>(url: string): Promise<unknown> {
const response = await fetch(url)
const data: ApiResponse<T> = await response.json() as ApiResponse<T>
if (data.error) {
throw new Error(data.error)
}
return data.data
}
function SWRProvider({ children }: PropsWithChildren<unknown>) { function SWRProvider({ children }: PropsWithChildren<unknown>) {
return ( return (
<SWRConfig <SWRConfig
value={{ value={{
fetcher: async (url: string) => { fetcher,
const data = await fetch(url).then((res) => res.json())
if (data.error) {
throw new Error(data.error)
}
return data
},
keepPreviousData: true keepPreviousData: true
}} }}
> >

View file

@ -10,6 +10,7 @@ import { useRouter } from "next/navigation"
import { useSessionSWR } from "@lib/use-session-swr" import { useSessionSWR } from "@lib/use-session-swr"
import { fetchWithUser } from "src/app/lib/fetch-with-user" import { fetchWithUser } from "src/app/lib/fetch-with-user"
import FadeIn from "@components/fade-in" import FadeIn from "@components/fade-in"
import { PostWithFiles } from "@lib/server/prisma"
type Props = { type Props = {
authorId: string authorId: string
@ -42,7 +43,7 @@ function VisibilityControl({
}) })
if (res.ok) { if (res.ok) {
const json = await res.json() const json = await res.json() as PostWithFiles
setVisibility(json.visibility) setVisibility(json.visibility)
router.refresh() router.refresh()
setToast({ setToast({

View file

@ -1,5 +1,5 @@
import Button from "@components/button" import Button from "@components/button"
import React from "react" import React, { ReactNode } from "react"
import styles from "./dropdown.module.css" import styles from "./dropdown.module.css"
import * as DropdownMenu from "@radix-ui/react-dropdown-menu" import * as DropdownMenu from "@radix-ui/react-dropdown-menu"
import { ArrowDown } from "react-feather" import { ArrowDown } from "react-feather"
@ -14,14 +14,11 @@ type ButtonDropdownProps = Props & Attrs
const ButtonDropdown: React.FC< const ButtonDropdown: React.FC<
React.PropsWithChildren<ButtonDropdownProps> React.PropsWithChildren<ButtonDropdownProps>
> = ({ type, ...props }) => { > = ({ type, ...props }) => {
if (!Array.isArray(props.children)) {
return null
}
return ( return (
<DropdownMenu.Root> <DropdownMenu.Root>
<div className={styles.dropdown} style={{ height: props.height }}> <div className={styles.dropdown} style={{ height: props.height }}>
{props.children[0]} <>
{Array.isArray(props.children) ? props.children[0] : props.children}
<DropdownMenu.Trigger <DropdownMenu.Trigger
style={{ style={{
display: "flex", display: "flex",
@ -36,13 +33,18 @@ const ButtonDropdown: React.FC<
className={styles.icon} className={styles.icon}
/> />
</DropdownMenu.Trigger> </DropdownMenu.Trigger>
{Array.isArray(props.children) ? (
<DropdownMenu.Portal> <DropdownMenu.Portal>
<DropdownMenu.Content align="end"> <DropdownMenu.Content align="end">
{props.children.slice(1).map((child, index) => ( {(props.children as ReactNode[])
?.slice(1)
.map((child, index) => (
<DropdownMenu.Item key={index}>{child}</DropdownMenu.Item> <DropdownMenu.Item key={index}>{child}</DropdownMenu.Item>
))} ))}
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Portal> </DropdownMenu.Portal>
) : null}
</>
</div> </div>
</DropdownMenu.Root> </DropdownMenu.Root>
) )

View file

@ -59,7 +59,7 @@ const PostList = ({
} }
} }
) )
const json = await res.json() const json = await res.json() as PostWithFiles[]
setPosts(json) setPosts(json)
setSearching(false) setSearching(false)
} }

View file

@ -1,4 +1,5 @@
import { ApiToken } from "@prisma/client" import { ApiToken } from "@prisma/client"
import { ApiResponse } from "src/app/(drift)/providers"
import useSWR from "swr" import useSWR from "swr"
type ConvertDateToString<T> = { type ConvertDateToString<T> = {
@ -35,15 +36,15 @@ export function useApiTokens({ userId, initialTokens }: UseApiTokens) {
} }
) )
const response = await res.json() const response = await res.json() as ApiResponse<SerializedApiToken>
if (response.error) { if (response.error) {
throw new Error(response.error) throw new Error(response.error)
return return
} }
mutate([...(data || []), response]) mutate([...(data || []), response.data])
return response as SerializedApiToken return response.data
} }
const expireToken = async (id: string) => { const expireToken = async (id: string) => {

View file

@ -1,3 +1,6 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { Gist, GistFile } from "./types" import { Gist, GistFile } from "./types"
async function fetchHelper(response: Response): Promise<Response> { async function fetchHelper(response: Response): Promise<Response> {
@ -6,7 +9,7 @@ async function fetchHelper(response: Response): Promise<Response> {
.get("content-type") .get("content-type")
?.includes("application/json") ?.includes("application/json")
const err = await (isJson ? response.json() : response.text()) const err = await (isJson ? response.json() : response.text())
throw new Error(err) throw new Error(err as string)
} }
return response return response
} }

View file

@ -25,7 +25,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
} }
}) })
return res.json(tokens) return res.json({ data: tokens })
} }
case "POST": { case "POST": {
const name = parseQueryParam(req.query.name) const name = parseQueryParam(req.query.name)
@ -33,7 +33,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
return res.status(400).json({ error: "Missing token name" }) return res.status(400).json({ error: "Missing token name" })
} }
const token = await createApiToken(userId, name) const token = await createApiToken(userId, name)
return res.json(token) return res.json({ data: token })
} }
case "DELETE": { case "DELETE": {
const tokenId = parseQueryParam(req.query.tokenId) const tokenId = parseQueryParam(req.query.tokenId)

2
types/index.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
import "@total-typescript/ts-reset";

View file

@ -1,5 +1,3 @@
import "@total-typescript/ts-reset";
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { User } from "next-auth" import type { User } from "next-auth"
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars