@@ -6,57 +6,63 @@ import { PrismaMapperEntity, PrismaMapperEntityField, PrismaMetaMapper } from '.
66import { Generics } from '@tsed/schema' ;
77import { SearchFilterRecord , SearchFilterValue } from './types.js' ;
88
9- export interface IBaseService {
10- onUpdate : Subject < { id : number , inputData : any , result : any } >
11- onDelete : Subject < { id : number , result : any } >
12- onCreate : Subject < { data : any , result : any } >
9+ export interface IBaseService < M > {
10+ onPostUpdate : Subject < { id : number , inputData : M , result : any } >
11+ onPreUpdate ?: Subject < { id : number , inputData : M } >
12+ onPreDelete ?: Subject < { id : number } >
13+ onPostDelete : Subject < { id : number , result : any } >
14+ onPreCreate ?: Subject < { data : M } >
15+ onPostCreate : Subject < { data : M , result : any } >
1316}
14- @Generics ( "T" )
15- export class BaseService < T > implements OnInit , IBaseService {
17+
18+ @Generics ( "T" , "M" )
19+ export class BaseService < T , M > implements OnInit , IBaseService < M > {
1620 /**
1721 * Service configuration options.
1822 *
19- * @property {Prisma.Repository } injectedRepository - A valid Prisma model repository required for this service.
20- * @property {PrismaService } prismaService - An instance of the PrismaService.
23+ * @property {string } tsedPrismaModelName - A valid Prisma model name required for this service.
24+ * @property {PrismaService } prismaService - An instance of the PrismaService used for computations and extensions .
2125 * @property {string } [relativePrismaFilePath="./prisma/schema.prisma"] - Optional path to the Prisma schema file. Defaults to "./prisma/schema.prisma".
2226 */
23- constructor ( public injectedRepository : any , private prismaService : any , relativePrismaFilePath ?: string ) {
27+ constructor ( public tsedPrismaModelName : any , private prismaService : any , relativePrismaFilePath ?: string ) {
2428 this . prismaFilePath = relativePrismaFilePath ?? "./prisma/schema.prisma"
2529 }
30+
2631 public prismaFilePath : string
2732 tablesInfo : Record < string , PrismaMapperEntity > = { }
2833
29- onUpdate : Subject < { id : number , inputData : any , result : any } > = new Subject ( )
30-
31- onCreate : Subject < { data : any , result : any } > = new Subject ( )
32-
33- onDelete : Subject < { id : number , result : any } > = new Subject ( )
34+ onPostUpdate : Subject < { id : number , inputData : M , result : any } > = new Subject ( )
35+ onPreUpdate ?: Subject < { id : number ; inputData : M ; } > = new Subject ( )
36+ onPreDelete ?: Subject < { id : number } > = new Subject ( )
37+ onPreCreate ?: Subject < { data : M } > = new Subject ( ) ;
38+ onPostCreate : Subject < { data : M , result : any } > = new Subject ( )
39+ onPostDelete : Subject < { id : number , result : any } > = new Subject ( )
3440
3541 get repository ( ) {
36- return this . injectedRepository as T ;
42+ return this . prismaService [ this . modelName ] as T ;
3743 }
3844
39- get fieldNames ( ) {
40- if ( this . injectedRepository ?. collection ) {
41- return Object . keys ( this . injectedRepository . collection . fields )
42- }
43- else if ( this . injectedRepository ?. fields ) {
44- return Object . keys ( this . injectedRepository . fields )
45- }
46- throw new Error ( 'injectedRepository has no fields, probably you passed wrong repository' ) ;
45+ get modelName ( ) {
46+ return _ . camelCase ( _ . split ( this . tsedPrismaModelName , 'Model' ) [ 0 ] ) as string ;
4747 }
4848
49- get currentModelName ( ) {
50- if ( this . injectedRepository ?. name ) {
51- return this . injectedRepository . name
49+ get fieldNames ( ) {
50+ // @ts -ignore
51+ if ( ( this . repository as any ) ?. collection ) {
52+ // @ts -ignore
53+ return Object . keys ( ( this . repository as any ) . collection . fields )
5254 }
53- if ( this . injectedRepository ?. collection ?. name ) {
54- return this . injectedRepository . collection . name ;
55+ // @ts -ignore
56+ else if ( ( this . repository as any ) ?. fields ) {
57+ // @ts -ignore
58+ return Object . keys ( ( this . repository as any ) . fields )
5559 }
60+ throw new Error ( 'repository has no fields, probably you passed wrong repository' ) ;
5661 }
5762
63+
5864 get currentModelInfo ( ) {
59- return this . tablesInfo [ this . currentModelName ]
65+ return this . tablesInfo [ this . modelName ]
6066 }
6167
6268 get currentModelFieldsMapping ( ) {
@@ -66,16 +72,15 @@ export class BaseService<T> implements OnInit, IBaseService {
6672 } , { } ) as Record < string , PrismaMapperEntityField >
6773 }
6874
69- extend < T > ( model : string , computedFields : Record < string , {
70- needs : Partial < Record < keyof T , boolean > >
71- compute : ( model : T ) => any
75+ extend < M > ( computedFields : Record < string , {
76+ needs : Partial < Record < keyof M , boolean > >
77+ compute : ( model : M ) => any
7278 } > ) {
73- const data = this . prismaService . $extends ( {
79+ this . prismaService . $extends ( {
7480 result : {
75- [ _ . camelCase ( model ) ] : computedFields as any
81+ [ this . modelName ] : computedFields as any
7682 }
7783 } )
78- this . injectedRepository = data [ _ . camelCase ( model ) ]
7984 }
8085
8186
@@ -84,20 +89,22 @@ export class BaseService<T> implements OnInit, IBaseService {
8489 this . tablesInfo = await prismaMapper . getTablesInfo ( )
8590 }
8691
87- async create ( data : any ) {
88- const result = await this . injectedRepository . create ( { data } ) ;
89- this . onCreate . next ( { data, result } ) ;
92+ async create ( data : M ) {
93+ this . onPreCreate ?. next ( { data } ) ;
94+ const result = await ( this . repository as any ) . create ( { data } ) ;
95+ this . onPostCreate . next ( { data, result } ) ;
9096 return result ;
9197 }
9298
9399 async deleteItem ( id : number ) {
94- const result = await this . injectedRepository . delete ( { where : { id } , select : { id : true } } ) ;
95- this . onDelete . next ( { id, result } ) ;
100+ this . onPreDelete ?. next ( { id } ) ;
101+ const result = await ( this . repository as any ) . delete ( { where : { id } , select : { id : true } } ) ;
102+ this . onPostDelete . next ( { id, result } ) ;
96103 return result ;
97104 }
98105
99106 async getOne ( id : number ) {
100- return ( await this . injectedRepository . findFirst ( { where : { id } } ) ) || { } ;
107+ return ( await ( this . repository as any ) . findFirst ( { where : { id } } ) ) || { } ;
101108 }
102109
103110 async update ( id : number , data : any , { relationOperation, relationvalueMapper } : {
@@ -115,8 +122,9 @@ export class BaseService<T> implements OnInit, IBaseService {
115122 } , {
116123 ...dataWithRelations
117124 } )
118- const result = await this . injectedRepository . update ( { where : { id } , data : finalData } ) ;
119- this . onUpdate . next ( { id, inputData : data , result } ) ;
125+ this . onPreUpdate ?. next ( { id, inputData : data } ) ;
126+ const result = await ( this . repository as any ) . update ( { where : { id } , data : finalData } ) ;
127+ this . onPostUpdate . next ( { id, inputData : data , result } ) ;
120128 return result ;
121129 }
122130
@@ -249,7 +257,7 @@ export class BaseService<T> implements OnInit, IBaseService {
249257 _ . set ( prismaFilters , `${ propertyName } .lte` , endValue ) ;
250258 _ . set ( prismaFilters , `${ propertyName } .gte` , startValue ) ;
251259 }
252-
260+
253261 } ,
254262 }
255263
@@ -293,13 +301,13 @@ export class BaseService<T> implements OnInit, IBaseService {
293301 where : prismaWhere ,
294302 select : selectFields
295303 } ;
296- const { _count : { id : total } } = await this . injectedRepository . aggregate ( {
304+ const { _count : { id : total } } = await ( this . repository as any ) . aggregate ( {
297305 where : prismaWhere ,
298306 _count : {
299307 id : true ,
300308 }
301309 } ) ;
302- const items = await this . injectedRepository . findMany ( properties ) ;
310+ const items = await ( this . repository as any ) . findMany ( properties ) ;
303311 return {
304312 total,
305313 items
0 commit comments