@@ -180,47 +180,82 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
180180 return ;
181181 }
182182
183- for ( const kind of [ 'select' , 'include' ] as const ) {
184- if ( args [ kind ] && typeof args [ kind ] === 'object' ) {
185- for ( const [ field , value ] of Object . entries < any > ( args [ kind ] ) ) {
186- const fieldInfo = resolveField ( this . options . modelMeta , model , field ) ;
187- if ( ! fieldInfo ) {
188- continue ;
189- }
183+ const selectors = [
184+ ( payload : any ) => ( { data : payload . select , kind : 'select' as const , isCount : false } ) ,
185+ ( payload : any ) => ( { data : payload . include , kind : 'include' as const , isCount : false } ) ,
186+ ( payload : any ) => ( {
187+ data : payload . select ?. _count ?. select ,
188+ kind : 'select' as const ,
189+ isCount : true ,
190+ } ) ,
191+ ( payload : any ) => ( {
192+ data : payload . include ?. _count ?. select ,
193+ kind : 'include' as const ,
194+ isCount : true ,
195+ } ) ,
196+ ] ;
197+
198+ for ( const selector of selectors ) {
199+ const { data, kind, isCount } = selector ( args ) ;
200+ if ( ! data || typeof data !== 'object' ) {
201+ continue ;
202+ }
190203
191- if ( this . isDelegateOrDescendantOfDelegate ( fieldInfo ?. type ) && value ) {
192- // delegate model, recursively inject hierarchy
193- if ( args [ kind ] [ field ] ) {
194- if ( args [ kind ] [ field ] === true ) {
195- // make sure the payload is an object
196- args [ kind ] [ field ] = { } ;
197- }
198- await this . injectSelectIncludeHierarchy ( fieldInfo . type , args [ kind ] [ field ] ) ;
204+ for ( const [ field , value ] of Object . entries < any > ( data ) ) {
205+ const fieldInfo = resolveField ( this . options . modelMeta , model , field ) ;
206+ if ( ! fieldInfo ) {
207+ continue ;
208+ }
209+
210+ if ( this . isDelegateOrDescendantOfDelegate ( fieldInfo ?. type ) && value ) {
211+ // delegate model, recursively inject hierarchy
212+ if ( data [ field ] ) {
213+ if ( data [ field ] === true ) {
214+ // make sure the payload is an object
215+ data [ field ] = { } ;
199216 }
217+ await this . injectSelectIncludeHierarchy ( fieldInfo . type , data [ field ] ) ;
200218 }
219+ }
201220
202- // refetch the field select/include value because it may have been
203- // updated during injection
204- const fieldValue = args [ kind ] [ field ] ;
221+ // refetch the field select/include value because it may have been
222+ // updated during injection
223+ const fieldValue = data [ field ] ;
205224
206- if ( fieldValue !== undefined ) {
207- if ( fieldValue . orderBy ) {
208- // `orderBy` may contain fields from base types
209- enumerate ( fieldValue . orderBy ) . forEach ( ( item ) =>
210- this . injectWhereHierarchy ( fieldInfo . type , item )
211- ) ;
212- }
225+ if ( fieldValue !== undefined ) {
226+ if ( fieldValue . orderBy ) {
227+ // `orderBy` may contain fields from base types
228+ enumerate ( fieldValue . orderBy ) . forEach ( ( item ) =>
229+ this . injectWhereHierarchy ( fieldInfo . type , item )
230+ ) ;
231+ }
213232
214- if ( this . injectBaseFieldSelect ( model , field , fieldValue , args , kind ) ) {
215- delete args [ kind ] [ field ] ;
216- } else if ( fieldInfo . isDataModel ) {
217- let nextValue = fieldValue ;
218- if ( nextValue === true ) {
219- // make sure the payload is an object
220- args [ kind ] [ field ] = nextValue = { } ;
233+ let injected = false ;
234+ if ( ! isCount ) {
235+ injected = await this . injectBaseFieldSelect ( model , field , fieldValue , args , kind ) ;
236+ if ( injected ) {
237+ delete data [ field ] ;
238+ }
239+ } else {
240+ const injectTarget = { [ kind ] : { } } ;
241+ injected = await this . injectBaseFieldSelect ( model , field , fieldValue , injectTarget , kind , true ) ;
242+ if ( injected ) {
243+ delete data [ field ] ;
244+ if ( Object . keys ( data ) . length === 0 ) {
245+ delete args [ kind ] [ '_count' ] ;
221246 }
222- await this . injectSelectIncludeHierarchy ( fieldInfo . type , nextValue ) ;
247+ const merged = deepmerge ( args [ kind ] , injectTarget [ kind ] ) ;
248+ args [ kind ] = merged ;
249+ }
250+ }
251+
252+ if ( ! injected && fieldInfo . isDataModel ) {
253+ let nextValue = fieldValue ;
254+ if ( nextValue === true ) {
255+ // make sure the payload is an object
256+ data [ field ] = nextValue = { } ;
223257 }
258+ await this . injectSelectIncludeHierarchy ( fieldInfo . type , nextValue ) ;
224259 }
225260 }
226261 }
@@ -272,7 +307,8 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
272307 field : string ,
273308 value : any ,
274309 selectInclude : any ,
275- context : 'select' | 'include'
310+ context : 'select' | 'include' ,
311+ forCount = false
276312 ) {
277313 const fieldInfo = resolveField ( this . options . modelMeta , model , field ) ;
278314 if ( ! fieldInfo ?. inheritedFrom ) {
@@ -286,24 +322,33 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
286322 const baseRelationName = this . makeAuxRelationName ( base ) ;
287323
288324 // prepare base layer select/include
289- // let selectOrInclude = 'select';
290325 let thisLayer : any ;
291326 if ( target . include ) {
292- // selectOrInclude = 'include';
293327 thisLayer = target . include ;
294328 } else if ( target . select ) {
295- // selectOrInclude = 'select';
296329 thisLayer = target . select ;
297330 } else {
298- // selectInclude = 'include';
299331 thisLayer = target . select = { } ;
300332 }
301333
302334 if ( base . name === fieldInfo . inheritedFrom ) {
303335 if ( ! thisLayer [ baseRelationName ] ) {
304336 thisLayer [ baseRelationName ] = { [ context ] : { } } ;
305337 }
306- thisLayer [ baseRelationName ] [ context ] [ field ] = value ;
338+ if ( forCount ) {
339+ if (
340+ ! thisLayer [ baseRelationName ] [ context ] [ '_count' ] ||
341+ typeof thisLayer [ baseRelationName ] [ context ] !== 'object'
342+ ) {
343+ thisLayer [ baseRelationName ] [ context ] [ '_count' ] = { } ;
344+ }
345+ thisLayer [ baseRelationName ] [ context ] [ '_count' ] = deepmerge (
346+ thisLayer [ baseRelationName ] [ context ] [ '_count' ] ,
347+ { select : { [ field ] : value } }
348+ ) ;
349+ } else {
350+ thisLayer [ baseRelationName ] [ context ] [ field ] = value ;
351+ }
307352 break ;
308353 } else {
309354 if ( ! thisLayer [ baseRelationName ] ) {
0 commit comments