import { initTRPC } from '@trpc/server'; import superjson from 'superjson'; import { sessionManager } from '../auth/session'; import { UserWithRelations } from '@fenghuo/common/user'; import { extractRequestInfo, RequestInfo } from '../utils/request'; // 定义上下文类型 export interface Context { user?: UserWithRelations; requestInfo: RequestInfo; } /** * 创建上下文函数(用于tRPC服务器) * @param opts 选项对象,包含请求对象 * @returns 上下文对象 */ export const createContext = async (opts?: { req?: any }): Promise => { // 提取请求信息(IP地址、User Agent等) const requestInfo = extractRequestInfo(opts?.req); // 如果有请求对象,尝试获取用户会话信息 if (opts?.req) { const session = await sessionManager.getSessionFromRequest(opts.req); if (session) { return { user: session.user, requestInfo }; } } // 没有有效的认证信息时返回空上下文 return { user: undefined, requestInfo }; }; // 初始化 tRPC const t = initTRPC.context().create({ transformer: superjson, errorFormatter({ shape, error }) { return { ...shape, data: { ...shape.data, code: error.code, }, }; }, }); export const publicProcedure = t.procedure; export const router = t.router; /** * 需要认证的过程 - 确保用户已登录 */ export const protectedProcedure = t.procedure.use(({ ctx, next }) => { // 检查用户是否已通过认证 if (!ctx.user) { throw new Error('未授权访问 - 请先登录'); } return next({ ctx: { ...ctx, user: ctx.user, // 确保用户存在,用户信息可通过 ctx.user 访问 }, }); });