From 50e4d0b13ca38a37b8d20c68dbdc02f4c1c48005 Mon Sep 17 00:00:00 2001 From: rharkor Date: Thu, 14 Sep 2023 17:31:10 +0200 Subject: [PATCH] feat: ssr rpc --- src/components/profile/profile-details.tsx | 7 ++-- src/components/profile/update-account.tsx | 16 ++++++--- src/lib/server/trpc.ts | 14 ++++++-- src/lib/trpc/api.ts | 38 ---------------------- src/lib/trpc/context.ts | 5 +-- src/lib/trpc/server.ts | 7 ++++ tsconfig.json | 2 +- 7 files changed, 37 insertions(+), 52 deletions(-) delete mode 100644 src/lib/trpc/api.ts create mode 100644 src/lib/trpc/server.ts diff --git a/src/components/profile/profile-details.tsx b/src/components/profile/profile-details.tsx index 6b773c3f..5c909c35 100644 --- a/src/components/profile/profile-details.tsx +++ b/src/components/profile/profile-details.tsx @@ -1,7 +1,10 @@ import { TDictionary } from "@/lib/langs" +import { serverTrpc } from "@/lib/trpc/server" import UpdateAccount from "./update-account" -export default function ProfileDetails({ dictionary }: { dictionary: TDictionary }) { +export default async function ProfileDetails({ dictionary }: { dictionary: TDictionary }) { + const serverAccount = await serverTrpc.me.getAccount() + return (
@@ -10,7 +13,7 @@ export default function ProfileDetails({ dictionary }: { dictionary: TDictionary {dictionary.profilePage.profileDetails.updateAccountDescription}

- +
) } diff --git a/src/components/profile/update-account.tsx b/src/components/profile/update-account.tsx index 668f37a5..a0fc2fb3 100644 --- a/src/components/profile/update-account.tsx +++ b/src/components/profile/update-account.tsx @@ -9,7 +9,7 @@ import * as z from "zod" import { useAccount } from "@/contexts/account" import { TDictionary } from "@/lib/langs" import { logger } from "@/lib/logger" -import { updateUserSchema } from "@/lib/schemas/user" +import { getAccountResponseSchema, updateUserSchema } from "@/lib/schemas/user" import { trpc } from "@/lib/trpc/client" import { handleMutationError } from "@/lib/utils/client-utils" import NeedSavePopup from "../need-save-popup" @@ -21,12 +21,20 @@ const nonSensibleSchema = updateUserSchema type INonSensibleForm = z.infer> -export default function UpdateAccount({ dictionary }: { dictionary: TDictionary }) { +export default function UpdateAccount({ + dictionary, + serverAccount, +}: { + dictionary: TDictionary + serverAccount: z.infer> +}) { const router = useRouter() const utils = trpc.useContext() const { update } = useSession() - const account = useAccount(dictionary) + const account = useAccount(dictionary, { + initialData: serverAccount, + }) const updateUserMutation = trpc.me.updateUser.useMutation({ onError: (error) => handleMutationError(error, dictionary, router), @@ -75,7 +83,7 @@ export default function UpdateAccount({ dictionary }: { dictionary: TDictionary label={dictionary.profilePage.profileDetails.username.label} placeholder={dictionary.profilePage.profileDetails.username.placeholder} type="text" - disabled={updateUserMutation.isLoading || !account.isFetched} + disabled={updateUserMutation.isLoading || account.isInitialLoading} form={form} name="username" /> diff --git a/src/lib/server/trpc.ts b/src/lib/server/trpc.ts index 2e6d4b90..54118296 100644 --- a/src/lib/server/trpc.ts +++ b/src/lib/server/trpc.ts @@ -1,6 +1,7 @@ import { initTRPC, TRPCError } from "@trpc/server" import superjson from "superjson" import { ZodError } from "zod" +import { getAuthApi } from "@/components/auth/require-auth" import { apiRateLimiter } from "../rate-limit" import { Context } from "../trpc/context" import { throwableErrorsMessages } from "../utils" @@ -41,11 +42,18 @@ const hasRateLimit = middleware(async (opts) => { }) export const publicProcedure = t.procedure.use(hasRateLimit) const isAuthenticated = middleware(async (opts) => { - const { ctx } = opts - if (!ctx.session) { + const { session } = await getAuthApi() + + if (!session) { throw new TRPCError({ code: "UNAUTHORIZED", message: throwableErrorsMessages.unauthorized }) } - return opts.next() + + return opts.next({ + ctx: { + ...opts.ctx, + session, + }, + }) }) const hasVerifiedEmail = middleware(async (opts) => { const { ctx } = opts diff --git a/src/lib/trpc/api.ts b/src/lib/trpc/api.ts deleted file mode 100644 index 51231619..00000000 --- a/src/lib/trpc/api.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { loggerLink } from "@trpc/client" -import { experimental_nextCacheLink as nextCacheLink } from "@trpc/next/app-dir/links/nextCache" -import { experimental_createTRPCNextAppDirServer as createTRPCNextAppDirServer } from "@trpc/next/app-dir/server" -import { cookies } from "next/headers" -import SuperJSON from "superjson" -import { getAuthApi } from "@/components/auth/require-auth" -import { appRouter } from "../server/routers/_app" - -/** - * This client invokes procedures directly on the server without fetching over HTTP. - */ -export const api = createTRPCNextAppDirServer({ - config() { - return { - transformer: SuperJSON, - links: [ - loggerLink({ - enabled: () => true, - }), - nextCacheLink({ - revalidate: 1, - router: appRouter, - async createContext() { - const { session } = await getAuthApi() - return { - session, - headers: { - cookie: cookies().toString(), - "x-trpc-source": "rsc-invoke", - }, - req: null, - } - }, - }), - ], - } - }, -}) diff --git a/src/lib/trpc/context.ts b/src/lib/trpc/context.ts index b9d0ef3c..b03f9b2f 100644 --- a/src/lib/trpc/context.ts +++ b/src/lib/trpc/context.ts @@ -1,12 +1,9 @@ import { FetchCreateContextFnOptions } from "@trpc/server/adapters/fetch" -import { getAuthApi } from "@/components/auth/require-auth" import { ITrpcContext } from "@/types" export async function createContext(opts?: FetchCreateContextFnOptions) { - const { session } = await getAuthApi() - const response: ITrpcContext = { - session, + session: null, headers: opts && Object.fromEntries(opts.req.headers), req: opts && opts.req, } diff --git a/src/lib/trpc/server.ts b/src/lib/trpc/server.ts new file mode 100644 index 00000000..40a23f58 --- /dev/null +++ b/src/lib/trpc/server.ts @@ -0,0 +1,7 @@ +import { createContext } from "./context" +import { appRouter } from "../server/routers/_app" + +/** + * This client invokes procedures directly on the server without fetching over HTTP. + */ +export const serverTrpc = appRouter.createCaller(await createContext()) diff --git a/tsconfig.json b/tsconfig.json index 5fa688b2..7f6f49cf 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "display": "Next.js", "compilerOptions": { - "target": "es5", + "target": "esnext", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true,