import { initTRPC, TRPCError } from "@trpc/server"; import { type CreateNextContextOptions } from "@trpc/server/adapters/next"; import { type Session } from "next-auth"; import superjson from "superjson"; import { ZodError } from "zod"; import { getServerAuthSession } from "~/server/auth"; import { db } from "~/server/db"; interface CreateContextOptions { session: Session | null; } const createInnerTRPCContext = (opts: CreateContextOptions) => { return { session: opts.session, db, }; }; export const createTRPCContext = async (opts: CreateNextContextOptions) => { const { req, res } = opts; // Get the session from the server using the getServerSession wrapper function const session = await getServerAuthSession({ req, res }); return createInnerTRPCContext({ session, }); }; const t = initTRPC.context().create({ transformer: superjson, errorFormatter({ shape, error }) { return { ...shape, data: { ...shape.data, zodError: error.cause instanceof ZodError ? error.cause.flatten() : null, }, }; }, }); export const createTRPCRouter = t.router; export const publicProcedure = t.procedure; export const protectedProcedure = t.procedure.use(({ ctx, next }) => { if (!ctx.session || !ctx.session.user) { throw new TRPCError({ code: "UNAUTHORIZED" }); } return next({ ctx: { // infers the `session` as non-nullable session: { ...ctx.session, user: ctx.session.user }, }, }); });