@@ -15,18 +15,22 @@ import {
15
15
isDelegateModel ,
16
16
resolveField ,
17
17
} from '../../cross' ;
18
- import type { CrudContract , DbClientContract } from '../../types' ;
18
+ import type { CrudContract , DbClientContract , EnhancementContext } from '../../types' ;
19
19
import type { InternalEnhancementOptions } from './create-enhancement' ;
20
20
import { Logger } from './logger' ;
21
21
import { DefaultPrismaProxyHandler , makeProxy } from './proxy' ;
22
22
import { QueryUtils } from './query-utils' ;
23
23
import { formatObject , prismaClientValidationError } from './utils' ;
24
24
25
- export function withDelegate < DbClient extends object > ( prisma : DbClient , options : InternalEnhancementOptions ) : DbClient {
25
+ export function withDelegate < DbClient extends object > (
26
+ prisma : DbClient ,
27
+ options : InternalEnhancementOptions ,
28
+ context : EnhancementContext | undefined
29
+ ) : DbClient {
26
30
return makeProxy (
27
31
prisma ,
28
32
options . modelMeta ,
29
- ( _prisma , model ) => new DelegateProxyHandler ( _prisma as DbClientContract , model , options ) ,
33
+ ( _prisma , model ) => new DelegateProxyHandler ( _prisma as DbClientContract , model , options , context ) ,
30
34
'delegate'
31
35
) ;
32
36
}
@@ -35,7 +39,12 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
35
39
private readonly logger : Logger ;
36
40
private readonly queryUtils : QueryUtils ;
37
41
38
- constructor ( prisma : DbClientContract , model : string , options : InternalEnhancementOptions ) {
42
+ constructor (
43
+ prisma : DbClientContract ,
44
+ model : string ,
45
+ options : InternalEnhancementOptions ,
46
+ private readonly context : EnhancementContext | undefined
47
+ ) {
39
48
super ( prisma , model , options ) ;
40
49
this . logger = new Logger ( prisma ) ;
41
50
this . queryUtils = new QueryUtils ( prisma , this . options ) ;
@@ -76,7 +85,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
76
85
args = args ? clone ( args ) : { } ;
77
86
78
87
this . injectWhereHierarchy ( model , args ?. where ) ;
79
- this . injectSelectIncludeHierarchy ( model , args ) ;
88
+ await this . injectSelectIncludeHierarchy ( model , args ) ;
80
89
81
90
// discriminator field is needed during post process to determine the
82
91
// actual concrete model type
@@ -166,7 +175,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
166
175
} ) ;
167
176
}
168
177
169
- private injectSelectIncludeHierarchy ( model : string , args : any ) {
178
+ private async injectSelectIncludeHierarchy ( model : string , args : any ) {
170
179
if ( ! args || typeof args !== 'object' ) {
171
180
return ;
172
181
}
@@ -186,7 +195,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
186
195
// make sure the payload is an object
187
196
args [ kind ] [ field ] = { } ;
188
197
}
189
- this . injectSelectIncludeHierarchy ( fieldInfo . type , args [ kind ] [ field ] ) ;
198
+ await this . injectSelectIncludeHierarchy ( fieldInfo . type , args [ kind ] [ field ] ) ;
190
199
}
191
200
}
192
201
@@ -208,7 +217,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
208
217
// make sure the payload is an object
209
218
args [ kind ] [ field ] = nextValue = { } ;
210
219
}
211
- this . injectSelectIncludeHierarchy ( fieldInfo . type , nextValue ) ;
220
+ await this . injectSelectIncludeHierarchy ( fieldInfo . type , nextValue ) ;
212
221
}
213
222
}
214
223
}
@@ -220,11 +229,11 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
220
229
this . injectBaseIncludeRecursively ( model , args ) ;
221
230
222
231
// include sub models downwards
223
- this . injectConcreteIncludeRecursively ( model , args ) ;
232
+ await this . injectConcreteIncludeRecursively ( model , args ) ;
224
233
}
225
234
}
226
235
227
- private buildSelectIncludeHierarchy ( model : string , args : any ) {
236
+ private async buildSelectIncludeHierarchy ( model : string , args : any ) {
228
237
args = clone ( args ) ;
229
238
const selectInclude : any = this . extractSelectInclude ( args ) || { } ;
230
239
@@ -248,7 +257,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
248
257
249
258
if ( ! selectInclude . select ) {
250
259
this . injectBaseIncludeRecursively ( model , selectInclude ) ;
251
- this . injectConcreteIncludeRecursively ( model , selectInclude ) ;
260
+ await this . injectConcreteIncludeRecursively ( model , selectInclude ) ;
252
261
}
253
262
return selectInclude ;
254
263
}
@@ -319,7 +328,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
319
328
this . injectBaseIncludeRecursively ( base . name , selectInclude . include [ baseRelationName ] ) ;
320
329
}
321
330
322
- private injectConcreteIncludeRecursively ( model : string , selectInclude : any ) {
331
+ private async injectConcreteIncludeRecursively ( model : string , selectInclude : any ) {
323
332
const modelInfo = getModelInfo ( this . options . modelMeta , model ) ;
324
333
if ( ! modelInfo ) {
325
334
return ;
@@ -333,13 +342,27 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
333
342
for ( const subModel of subModels ) {
334
343
// include sub model relation field
335
344
const subRelationName = this . makeAuxRelationName ( subModel ) ;
345
+ const includePayload : any = { } ;
346
+
347
+ if ( this . options . processIncludeRelationPayload ) {
348
+ // use the callback in options to process the include payload, so enhancements
349
+ // like 'policy' can do extra work (e.g., inject policy rules)
350
+ await this . options . processIncludeRelationPayload (
351
+ this . prisma ,
352
+ subModel . name ,
353
+ includePayload ,
354
+ this . options ,
355
+ this . context
356
+ ) ;
357
+ }
358
+
336
359
if ( selectInclude . select ) {
337
- selectInclude . include = { [ subRelationName ] : { } , ...selectInclude . select } ;
360
+ selectInclude . include = { [ subRelationName ] : includePayload , ...selectInclude . select } ;
338
361
delete selectInclude . select ;
339
362
} else {
340
- selectInclude . include = { [ subRelationName ] : { } , ...selectInclude . include } ;
363
+ selectInclude . include = { [ subRelationName ] : includePayload , ...selectInclude . include } ;
341
364
}
342
- this . injectConcreteIncludeRecursively ( subModel . name , selectInclude . include [ subRelationName ] ) ;
365
+ await this . injectConcreteIncludeRecursively ( subModel . name , selectInclude . include [ subRelationName ] ) ;
343
366
}
344
367
}
345
368
@@ -480,7 +503,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
480
503
args = clone ( args ) ;
481
504
482
505
await this . injectCreateHierarchy ( model , args ) ;
483
- this . injectSelectIncludeHierarchy ( model , args ) ;
506
+ await this . injectSelectIncludeHierarchy ( model , args ) ;
484
507
485
508
if ( this . options . logPrismaQuery ) {
486
509
this . logger . info ( `[delegate] \`create\` ${ this . getModelName ( model ) } : ${ formatObject ( args ) } ` ) ;
@@ -702,7 +725,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
702
725
703
726
args = clone ( args ) ;
704
727
this . injectWhereHierarchy ( this . model , ( args as any ) ?. where ) ;
705
- this . injectSelectIncludeHierarchy ( this . model , args ) ;
728
+ await this . injectSelectIncludeHierarchy ( this . model , args ) ;
706
729
if ( args . create ) {
707
730
this . doProcessCreatePayload ( this . model , args . create ) ;
708
731
}
@@ -721,7 +744,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
721
744
args = clone ( args ) ;
722
745
723
746
await this . injectUpdateHierarchy ( db , model , args ) ;
724
- this . injectSelectIncludeHierarchy ( model , args ) ;
747
+ await this . injectSelectIncludeHierarchy ( model , args ) ;
725
748
726
749
if ( this . options . logPrismaQuery ) {
727
750
this . logger . info ( `[delegate] \`update\` ${ this . getModelName ( model ) } : ${ formatObject ( args ) } ` ) ;
@@ -915,7 +938,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
915
938
}
916
939
917
940
return this . queryUtils . transaction ( this . prisma , async ( tx ) => {
918
- const selectInclude = this . buildSelectIncludeHierarchy ( this . model , args ) ;
941
+ const selectInclude = await this . buildSelectIncludeHierarchy ( this . model , args ) ;
919
942
920
943
// make sure id fields are selected
921
944
const idFields = this . getIdFields ( this . model ) ;
@@ -967,6 +990,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
967
990
968
991
private async doDelete ( db : CrudContract , model : string , args : any ) : Promise < unknown > {
969
992
this . injectWhereHierarchy ( model , args . where ) ;
993
+ await this . injectSelectIncludeHierarchy ( model , args ) ;
970
994
971
995
if ( this . options . logPrismaQuery ) {
972
996
this . logger . info ( `[delegate] \`delete\` ${ this . getModelName ( model ) } : ${ formatObject ( args ) } ` ) ;
0 commit comments