1- import { initTRPC , TRPCError } from "@trpc/server" ;
1+ import { initTRPC , TRPCError , type TRPCProcedureBuilder } from "@trpc/server" ;
22import { flattenError , ZodError } from "zod" ;
33import type { TRPCContext } from "./context.js" ;
44
@@ -18,18 +18,49 @@ const t = initTRPC.context<TRPCContext>().create({
1818export const router = t . router ;
1919export const publicProcedure = t . procedure ;
2020
21- export const protectedProcedure = t . procedure . use ( ( { ctx, next } ) => {
22- if ( ! ctx . session || ! ctx . user ) {
23- throw new TRPCError ( {
24- code : "UNAUTHORIZED" ,
25- message : "Authentication required" ,
21+ // Derive type from publicProcedure to stay in sync with initTRPC config.
22+ // Explicit annotation required to avoid TS2742 (non-portable inferred type).
23+ type ProtectedProcedure =
24+ typeof publicProcedure extends TRPCProcedureBuilder <
25+ infer TContext ,
26+ infer TMeta ,
27+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28+ infer TContextOverrides ,
29+ infer TInputIn ,
30+ infer TInputOut ,
31+ infer TOutputIn ,
32+ infer TOutputOut ,
33+ infer TCaller
34+ >
35+ ? TRPCProcedureBuilder <
36+ TContext ,
37+ TMeta ,
38+ {
39+ session : NonNullable < TRPCContext [ "session" ] > ;
40+ user : NonNullable < TRPCContext [ "user" ] > ;
41+ } ,
42+ TInputIn ,
43+ TInputOut ,
44+ TOutputIn ,
45+ TOutputOut ,
46+ TCaller
47+ >
48+ : never ;
49+
50+ export const protectedProcedure : ProtectedProcedure = t . procedure . use (
51+ ( { ctx, next } ) => {
52+ if ( ! ctx . session || ! ctx . user ) {
53+ throw new TRPCError ( {
54+ code : "UNAUTHORIZED" ,
55+ message : "Authentication required" ,
56+ } ) ;
57+ }
58+ return next ( {
59+ ctx : {
60+ ...ctx ,
61+ session : ctx . session ,
62+ user : ctx . user ,
63+ } ,
2664 } ) ;
27- }
28- return next ( {
29- ctx : {
30- ...ctx ,
31- session : ctx . session ,
32- user : ctx . user ,
33- } ,
34- } ) ;
35- } ) ;
65+ } ,
66+ ) ;
0 commit comments