@@ -12,12 +12,14 @@ export type ImplArgs<I extends z.ZodType, Env> = {
1212export type SafeRpcHandler <
1313 I extends z . ZodType ,
1414 O extends z . ZodType ,
15- InferredOutput = z . infer < O >
15+ InferredOutput = z . infer < O > ,
16+ Meta = unknown
1617> = {
1718 ( input : z . infer < I > ) : Promise < InferredOutput > ;
1819 _def : {
1920 input : I ;
2021 output : O ;
22+ meta : Meta ;
2123 } ;
2224 [ SafeRpcMethodSymbol ] : true ;
2325} ;
@@ -28,11 +30,13 @@ function createHandler<
2830 I extends z . ZodType ,
2931 O extends z . ZodType ,
3032 Env ,
31- T extends DurableObject < Env >
33+ T extends DurableObject < Env > ,
34+ Meta = unknown
3235> (
3336 fn : ( args : ImplArgs < I , Env > ) => MaybePromise < z . infer < O > > ,
3437 inputSchema : I ,
35- outputSchema ?: O
38+ outputSchema ?: O ,
39+ meta ?: Meta
3640) {
3741 const handler = async function ( this : T , rawInput : z . infer < I > ) {
3842 const parsedInput = await inputSchema . parseAsync ( rawInput ) ;
@@ -49,6 +53,7 @@ function createHandler<
4953 value : {
5054 input : inputSchema ,
5155 output : outputSchema ?? z . unknown ( ) ,
56+ meta : meta ?? { } ,
5257 } ,
5358 enumerable : true ,
5459 } ,
@@ -61,39 +66,88 @@ function createHandler<
6166 return handlerWithDef ;
6267}
6368
64- function routeBuilder < Env , T extends DurableObject < Env > > ( ) {
65- return {
66- input < I extends z . ZodType > ( inputSchema : I ) {
67- return {
68- output < O extends z . ZodType > ( outputSchema : O ) {
69- return {
70- implement (
71- fn : ( this : T , args : ImplArgs < I , Env > ) => MaybePromise < z . infer < O > >
72- ) {
73- return createHandler (
74- fn ,
75- inputSchema ,
76- outputSchema
77- ) as SafeRpcHandler < I , O > ;
78- } ,
79- } ;
80- } ,
81- implement < R > ( fn : ( this : T , args : ImplArgs < I , Env > ) => MaybePromise < R > ) {
82- return createHandler ( fn , inputSchema ) as SafeRpcHandler <
83- I ,
84- z . ZodUnknown ,
85- R
86- > ;
87- } ,
88- } ;
89- } ,
90- } ;
69+ class RouteBuilder <
70+ Env ,
71+ T extends DurableObject < Env > ,
72+ I extends z . ZodType | undefined = undefined ,
73+ O extends z . ZodType | undefined = undefined ,
74+ Meta = unknown
75+ > {
76+ private inputSchema ?: I ;
77+ private outputSchema ?: O ;
78+ private metaData ?: Meta ;
79+
80+ constructor ( inputSchema ?: I , outputSchema ?: O , metaData ?: Meta ) {
81+ this . inputSchema = inputSchema ;
82+ this . outputSchema = outputSchema ;
83+ this . metaData = metaData ;
84+ return this ;
85+ }
86+
87+ input < InputSchema extends z . ZodType > (
88+ inputSchema : InputSchema
89+ ) : RouteBuilder < Env , T , InputSchema , O , Meta > {
90+ if ( this . inputSchema ) throw new Error ( "Input schema already set" ) ;
91+ return new RouteBuilder < Env , T , InputSchema , O , Meta > (
92+ inputSchema ,
93+ this . outputSchema ,
94+ this . metaData
95+ ) ;
96+ }
97+
98+ output < OutputSchema extends z . ZodType > (
99+ this : RouteBuilder < Env , T , I , undefined , Meta > ,
100+ outputSchema : OutputSchema
101+ ) : RouteBuilder < Env , T , I , OutputSchema , Meta > {
102+ if ( this . outputSchema ) throw new Error ( "Output schema already set" ) ;
103+ return new RouteBuilder < Env , T , I , OutputSchema , Meta > (
104+ this . inputSchema ,
105+ outputSchema ,
106+ this . metaData
107+ ) ;
108+ }
109+
110+ meta < MetaData > ( metaData : MetaData ) : RouteBuilder < Env , T , I , O , MetaData > {
111+ if ( this . metaData ) throw new Error ( "Metadata already set" ) ;
112+ return new RouteBuilder < Env , T , I , O , MetaData > (
113+ this . inputSchema ,
114+ this . outputSchema ,
115+ metaData
116+ ) ;
117+ }
118+
119+ implement < R > (
120+ this : RouteBuilder < Env , T , I , undefined , Meta > ,
121+ fn : I extends z . ZodType
122+ ? ( this : T , args : ImplArgs < I , Env > ) => MaybePromise < R >
123+ : never
124+ ) : I extends z . ZodType ? SafeRpcHandler < I , z . ZodUnknown , R , Meta > : never ;
125+
126+ implement (
127+ this : RouteBuilder < Env , T , I , O , Meta > ,
128+ fn : I extends z . ZodType
129+ ? O extends z . ZodType
130+ ? ( this : T , args : ImplArgs < I , Env > ) => MaybePromise < z . infer < O > >
131+ : never
132+ : never
133+ ) : I extends z . ZodType
134+ ? O extends z . ZodType
135+ ? SafeRpcHandler < I , O , z . infer < O > , Meta >
136+ : never
137+ : never ;
138+
139+ implement (
140+ fn : ( this : T , args : ImplArgs < any , Env > ) => MaybePromise < any >
141+ ) : SafeRpcHandler < any , any , any , Meta > {
142+ if ( ! this . inputSchema ) throw new Error ( "Input schema is required" ) ;
143+ return createHandler (
144+ fn ,
145+ this . inputSchema as z . ZodType ,
146+ this . outputSchema as z . ZodType | undefined ,
147+ this . metaData
148+ ) as SafeRpcHandler < any , any , any , Meta > ;
149+ }
91150}
92-
93- type RouteBuilder < Env , T extends DurableObject < Env > > = ReturnType <
94- typeof routeBuilder < Env , T >
95- > ;
96-
97151type AnyDurableClass < T extends DurableObject , Env > = new (
98152 ctx : DurableObjectState ,
99153 env : Env
@@ -102,15 +156,15 @@ type AnyDurableClass<T extends DurableObject, Env> = new (
102156export function SafeDurableObjectBuilder <
103157 Env ,
104158 T extends DurableObject < Env > ,
105- Router extends Record < string , SafeRpcHandler < any , any > >
159+ Router extends Record < string , SafeRpcHandler < any , any , any , any > >
106160> (
107161 BaseClass : AnyDurableClass < T , Env > ,
108162 routerBuilder : ( builder : RouteBuilder < Env , T > ) => Router
109163) {
110164 // create a extended class so that we don't pollute the base class with the router
111165 class BaseClassWithSafeRpc extends BaseClass { }
112166
113- const router = routerBuilder ( routeBuilder ( ) ) ;
167+ const router = routerBuilder ( new RouteBuilder < Env , T > ( ) ) ;
114168
115169 Object . defineProperties (
116170 BaseClassWithSafeRpc . prototype ,
@@ -135,6 +189,6 @@ export function SafeDurableObjectBuilder<
135189
136190export function isSafeDurableObjectMethod (
137191 method : any
138- ) : method is SafeRpcHandler < any , any > {
192+ ) : method is SafeRpcHandler < any , any , any , any > {
139193 return method && method [ SafeRpcMethodSymbol ] === true ;
140194}
0 commit comments