@@ -82,12 +82,30 @@ export const createObjectImplementer = <
8282 table,
8383 refName,
8484 readAction = "read" as Action ,
85- extend ,
85+ adjust ,
8686 } : {
87+ /**
88+ * The table you want to be used as reference for the object creation.
89+ */
8790 table : ExplicitTableName ;
91+ /**
92+ * The name you want this object to have in your graphql schema.
93+ * Rumble will create a reasonable default if not specified.
94+ */
8895 refName ?: RefName ;
96+ /**
97+ * The action used for read access to the table.
98+ * Defaults to "read".
99+ */
89100 readAction ?: Action ;
90- extend ?:
101+ /**
102+ * A function which can be used to adjust the fields of the object.
103+ * You can extend the object by specifying fields that do not exist as
104+ * per your db schema, or overwrite existing fields with the same name.
105+ * In case you do overwrite, rumble will set proper nullability and
106+ * subscription properties if you do not specify them explicitly.
107+ */
108+ adjust ?:
91109 | ( (
92110 t : DrizzleObjectFieldBuilder <
93111 SchemaBuilder [ "$inferSchemaTypes" ] ,
@@ -184,8 +202,56 @@ export const createObjectImplementer = <
184202 }
185203 } ;
186204
205+ // in case the user makes adjustments we want to store away which
206+ // pothos function was called with what config
207+ // this is mapped to the ref which later can be used to
208+ // reference these parameters while iterating over the fields
209+ // and checking against the userAdjustments object
210+ const configMap = new Map <
211+ any ,
212+ {
213+ creatorFunction : any ;
214+ config : any ;
215+ }
216+ > ( ) ;
217+ // stores the results of the user adjustments
218+ // also stores all the used pothos functions and the configs
219+ // provided by the user so we can extend that if necessary
220+ const userAdjustments =
221+ adjust ?.(
222+ new Proxy ( t , {
223+ get : ( target , prop ) => {
224+ if ( typeof ( target as any ) [ prop ] === "function" ) {
225+ return ( config : any ) => {
226+ const ref = ( target as any ) [ prop ] ( config ) ;
227+ configMap . set ( ref , {
228+ config,
229+ creatorFunction : ( target as any ) [ prop ] ,
230+ } ) ;
231+ return ref ;
232+ } ;
233+ }
234+
235+ return ( target as any ) [ prop ] ;
236+ } ,
237+ } ) as any ,
238+ ) ?? { } ;
239+
187240 const fields = Object . entries ( columns ) . reduce (
188241 ( acc , [ key , value ] ) => {
242+ if ( userAdjustments [ key ] ) {
243+ const { config, creatorFunction } = configMap . get (
244+ userAdjustments [ key ] ,
245+ ) ! ;
246+
247+ if ( typeof config . nullable !== "boolean" ) {
248+ config . nullable = ! value . notNull ;
249+ }
250+
251+ userAdjustments [ key ] = creatorFunction ( config ) ;
252+ return acc ;
253+ }
254+
189255 if ( isEnumSchema ( value ) ) {
190256 const enumImpl = enumImplementer ( {
191257 enumColumn : value ,
@@ -234,20 +300,39 @@ export const createObjectImplementer = <
234300 filterSpecifier = "single" ;
235301 }
236302
303+ const subscribe = ( subscriptions : any , element : any ) => {
304+ relationTable . registerOnInstance ( {
305+ instance : subscriptions ,
306+ action : "created" ,
307+ } ) ;
308+ relationTable . registerOnInstance ( {
309+ instance : subscriptions ,
310+ action : "removed" ,
311+ } ) ;
312+ } ;
313+
314+ if ( userAdjustments [ key ] ) {
315+ const { config, creatorFunction } = configMap . get (
316+ userAdjustments [ key ] ,
317+ ) ! ;
318+
319+ if ( typeof config . nullable !== "boolean" ) {
320+ config . nullable = nullable ;
321+ }
322+
323+ if ( typeof config . subscribe !== "function" ) {
324+ config . subscribe = subscribe ;
325+ }
326+
327+ userAdjustments [ key ] = creatorFunction ( config ) ;
328+ return acc ;
329+ }
330+
237331 ( acc as any ) [ key ] = t . relation ( key , {
238332 args : {
239333 where : t . arg ( { type : WhereArg , required : false } ) ,
240334 } ,
241- subscribe : ( subscriptions , element ) => {
242- relationTable . registerOnInstance ( {
243- instance : subscriptions ,
244- action : "created" ,
245- } ) ;
246- relationTable . registerOnInstance ( {
247- instance : subscriptions ,
248- action : "removed" ,
249- } ) ;
250- } ,
335+ subscribe,
251336 nullable,
252337 query : ( args : any , ctx : any ) => {
253338 return ctx . abilities [ relationSchema . tsName ] . filter ( readAction , {
@@ -263,16 +348,11 @@ export const createObjectImplementer = <
263348 > ,
264349 ) ;
265350
266- return extend
267- ? {
268- ...fields ,
269- ...relations ,
270- ...( extend ( t as any ) ?? { } ) ,
271- }
272- : {
273- ...fields ,
274- ...relations ,
275- } ;
351+ return {
352+ ...fields ,
353+ ...relations ,
354+ ...userAdjustments ,
355+ } ;
276356 } ,
277357 } ) ;
278358 } ;
0 commit comments