casualroom/apps/fenghuo/api/src/trpc/base.ts

72 lines
1.6 KiB
TypeScript
Raw Normal View History

2025-07-28 07:50:50 +08:00
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<Context> => {
// 提取请求信息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<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 访问
},
});
});