From b7d0c4331c2cdb85844534931026789a81a6828e Mon Sep 17 00:00:00 2001 From: notmd <33456881+notmd@users.noreply.github.com> Date: Tue, 7 Feb 2023 17:56:59 +0700 Subject: [PATCH] Ts strict mode (#1288) part of #879 --- website/package-lock.json | 13 +++++++++++++ website/package.json | 1 + website/src/components/DataTable.tsx | 2 +- website/src/components/UserTable.tsx | 4 ++-- website/src/lib/users.ts | 17 +++++++++++------ website/src/pages/auth/signin.tsx | 11 ++++++----- website/src/pages/auth/verify.tsx | 5 +++-- website/src/pages/messages/[id]/index.tsx | 13 +++++++++---- website/src/pages/tasks/all.tsx | 2 +- website/types/next-auth.d.ts | 7 ++++--- 10 files changed, 51 insertions(+), 24 deletions(-) diff --git a/website/package-lock.json b/website/package-lock.json index 3b8220e5..a785fe29 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -68,6 +68,7 @@ "@storybook/testing-library": "^0.0.13", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", + "@types/accept-language-parser": "^1.5.3", "@types/node": "^18.11.17", "@types/react": "18.0.26", "@typescript-eslint/eslint-plugin": "^5.47.1", @@ -12619,6 +12620,12 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "devOptional": true }, + "node_modules/@types/accept-language-parser": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/accept-language-parser/-/accept-language-parser-1.5.3.tgz", + "integrity": "sha512-S8oM29O6nnRC3/+rwYV7GBYIIgNIZ52PCxqBG7OuItq9oATnYWy8FfeLKwvq5F7pIYjeeBSCI7y+l+Z9UEQpVQ==", + "dev": true + }, "node_modules/@types/aria-query": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", @@ -47865,6 +47872,12 @@ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "devOptional": true }, + "@types/accept-language-parser": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@types/accept-language-parser/-/accept-language-parser-1.5.3.tgz", + "integrity": "sha512-S8oM29O6nnRC3/+rwYV7GBYIIgNIZ52PCxqBG7OuItq9oATnYWy8FfeLKwvq5F7pIYjeeBSCI7y+l+Z9UEQpVQ==", + "dev": true + }, "@types/aria-query": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.1.tgz", diff --git a/website/package.json b/website/package.json index 7ab3f3d8..551a20c6 100644 --- a/website/package.json +++ b/website/package.json @@ -86,6 +86,7 @@ "@storybook/testing-library": "^0.0.13", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", + "@types/accept-language-parser": "^1.5.3", "@types/node": "^18.11.17", "@types/react": "18.0.26", "@typescript-eslint/eslint-plugin": "^5.47.1", diff --git a/website/src/components/DataTable.tsx b/website/src/components/DataTable.tsx index f25f30dd..35246bf7 100644 --- a/website/src/components/DataTable.tsx +++ b/website/src/components/DataTable.tsx @@ -84,7 +84,7 @@ export const DataTable = ({ } else { newValues = filterValues.map((oldValue) => (oldValue.id === value.id ? value : oldValue)); } - onFilterChange(newValues); + onFilterChange && onFilterChange(newValues); }; return ( <> diff --git a/website/src/components/UserTable.tsx b/website/src/components/UserTable.tsx index 57a96c95..ab05d065 100644 --- a/website/src/components/UserTable.tsx +++ b/website/src/components/UserTable.tsx @@ -76,14 +76,14 @@ export const UserTable = memo(function UserTable() { const toPreviousPage = () => { setPagination({ - cursor: data.prev, + cursor: data?.prev || "", direction: "back", }); }; const toNextPage = () => { setPagination({ - cursor: data.next, + cursor: data?.next || "", direction: "forward", }); }; diff --git a/website/src/lib/users.ts b/website/src/lib/users.ts index d9e32937..d17dda37 100644 --- a/website/src/lib/users.ts +++ b/website/src/lib/users.ts @@ -32,9 +32,8 @@ const getUserLanguage = (req: NextApiRequest): string => { * * @param {string} id The user's web auth id. * - * @return {BackendUserCore} The most specific auth type and id for the user. */ -const getBackendUserCore = async (id: string) => { +const getBackendUserCore = async (id: string): Promise => { const user = await prisma.user.findUnique({ where: { id }, select: { @@ -44,21 +43,27 @@ const getBackendUserCore = async (id: string) => { }, }); + if (!user) { + return null; + } + // If there are no linked accounts, just use what we have locally. if (user.accounts.length === 0) { return { id: user.id, - display_name: user.name, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + display_name: user.name!, auth_method: "local", - } as BackendUserCore; + }; } // Otherwise, use the first linked account that the user created. return { id: user.accounts[0].providerAccountId, - display_name: user.name, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + display_name: user.name!, auth_method: user.accounts[0].provider, - } as BackendUserCore; + }; }; export { getBackendUserCore, getUserLanguage }; diff --git a/website/src/pages/auth/signin.tsx b/website/src/pages/auth/signin.tsx index 62cd93f7..d66ff60c 100644 --- a/website/src/pages/auth/signin.tsx +++ b/website/src/pages/auth/signin.tsx @@ -7,9 +7,10 @@ import { GetServerSideProps } from "next"; import Head from "next/head"; import Link from "next/link"; import { useRouter } from "next/router"; -import { getProviders, signIn } from "next-auth/react"; +import { BuiltInProviderType } from "next-auth/providers"; +import { ClientSafeProvider, getProviders, signIn } from "next-auth/react"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; -import React, { useEffect, useRef, useState } from "react"; +import React, { ReactNode, useEffect, useRef, useState } from "react"; import { useForm } from "react-hook-form"; import { AuthLayout } from "src/components/AuthLayout"; import { CloudFlareCaptcha } from "src/components/CloudflareCaptcha"; @@ -48,7 +49,7 @@ const errorMessages: Record = { }; interface SigninProps { - providers: Awaited>; + providers: Record; } function Signin({ providers }: SigninProps) { @@ -137,7 +138,7 @@ function Signin({ providers }: SigninProps) { ); } -Signin.getLayout = (page) => ( +Signin.getLayout = (page: ReactNode) => (
{page} @@ -151,7 +152,7 @@ const emailSigninCaptcha = boolean(process.env.NEXT_PUBLIC_ENABLE_EMAIL_SIGNIN_C const EmailSignInForm = ({ providerId }: { providerId: string }) => { const { register, handleSubmit } = useForm<{ email: string }>(); - const captcha = useRef(); + const captcha = useRef(null); const [captchaSuccess, setCaptchaSuccess] = useState(false); const signinWithEmail = (data: { email: string }) => { signIn(providerId, { diff --git a/website/src/pages/auth/verify.tsx b/website/src/pages/auth/verify.tsx index d7a64a63..0e4ce1f9 100644 --- a/website/src/pages/auth/verify.tsx +++ b/website/src/pages/auth/verify.tsx @@ -1,4 +1,5 @@ import { useColorMode } from "@chakra-ui/react"; +import { GetServerSideProps } from "next"; import Head from "next/head"; import { getCsrfToken, getProviders } from "next-auth/react"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; @@ -22,7 +23,7 @@ export default function Verify() { ); } -export async function getServerSideProps({ locale }) { +export const getServerSideProps: GetServerSideProps = async ({ locale = "en" }) => { const csrfToken = await getCsrfToken(); const providers = await getProviders(); return { @@ -32,4 +33,4 @@ export async function getServerSideProps({ locale }) { ...(await serverSideTranslations(locale, ["common"])), }, }; -} +}; diff --git a/website/src/pages/messages/[id]/index.tsx b/website/src/pages/messages/[id]/index.tsx index 0092a843..e50e60cf 100644 --- a/website/src/pages/messages/[id]/index.tsx +++ b/website/src/pages/messages/[id]/index.tsx @@ -1,4 +1,5 @@ import { Box, Card, Text, useColorModeValue } from "@chakra-ui/react"; +import { GetServerSideProps, InferGetServerSidePropsType } from "next"; import Head from "next/head"; import { useTranslation } from "next-i18next"; import { serverSideTranslations } from "next-i18next/serverSideTranslations"; @@ -10,7 +11,7 @@ import { get } from "src/lib/api"; import { Message } from "src/types/Conversation"; import useSWRImmutable from "swr/immutable"; -const MessageDetail = ({ id }: { id: string }) => { +const MessageDetail = ({ id }: InferGetServerSidePropsType) => { const { t } = useTranslation(["message", "common"]); const backgroundColor = useColorModeValue("white", "gray.800"); @@ -49,11 +50,15 @@ const MessageDetail = ({ id }: { id: string }) => { ); }; -MessageDetail.getLayout = (page) => getDashboardLayout(page); +MessageDetail.getLayout = getDashboardLayout; -export const getServerSideProps = async ({ locale, query }) => ({ +export const getServerSideProps: GetServerSideProps<{ id: string }, { id: string }> = async ({ + locale = "en", + params, +}) => ({ props: { - id: query.id, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + id: params!.id, ...(await serverSideTranslations(locale, ["common", "message", "labelling"])), }, }); diff --git a/website/src/pages/tasks/all.tsx b/website/src/pages/tasks/all.tsx index 01954c2f..d71096ee 100644 --- a/website/src/pages/tasks/all.tsx +++ b/website/src/pages/tasks/all.tsx @@ -16,6 +16,6 @@ const AllTasks = () => { ); }; -AllTasks.getLayout = (page) => getDashboardLayout(page); +AllTasks.getLayout = getDashboardLayout; export default AllTasks; diff --git a/website/types/next-auth.d.ts b/website/types/next-auth.d.ts index ed126deb..f0f381d4 100644 --- a/website/types/next-auth.d.ts +++ b/website/types/next-auth.d.ts @@ -1,5 +1,4 @@ -import NextAuth, { DefaultSession } from "next-auth"; -import { JWT } from "next-auth/jwt"; +import { DefaultSession } from "next-auth"; declare module "next-auth" { interface Session { @@ -17,9 +16,11 @@ declare module "next-auth" { declare module "next-auth/jwt" { interface JWT { /** The user's role. */ - role?: string; + role: string; /** True when the user is new. */ isNew?: boolean; + + sub: string; /** Iso timestamp of the user's acceptance of the terms of service */ tosAcceptanceDate?: string; }