1+ import { InvocationArgs , InvocationContext } from "@loopback/context" ;
2+ import { Application , CoreBindings } from "@loopback/core" ;
13import {
24 juggler ,
35 Class ,
46 DefaultCrudRepository ,
7+ EntityNotFoundError ,
58 DataObject ,
69 Options ,
710 Entity ,
811 Filter ,
912 Where ,
13+ Fields ,
1014 Count ,
1115} from "@loopback/repository" ;
1216
1317import { Ctor } from "../types" ;
1418
19+ /**
20+ * Repository Config
21+ */
22+ export interface FilterContext <
23+ Model extends Entity ,
24+ ModelID ,
25+ ModelRelations extends object = { }
26+ > {
27+ target : DefaultCrudRepository < Model , ModelID , ModelRelations > ;
28+ methodName : keyof DefaultCrudRepository < Model , ModelID , ModelRelations > ;
29+ args : InvocationArgs ;
30+ invocationContext : InvocationContext ;
31+ }
32+
33+ export interface RepositoryConfig <
34+ Model extends Entity ,
35+ ModelID ,
36+ ModelRelations extends object = { }
37+ > {
38+ id : keyof Model ;
39+ where : (
40+ context : FilterContext < Model , ModelID , ModelRelations > ,
41+ where : Where < Model >
42+ ) => Promise < Where < Model > > ;
43+ fields : (
44+ context : FilterContext < Model , ModelID , ModelRelations > ,
45+ fields : Fields < Model >
46+ ) => Promise < Fields < Model > > ;
47+ }
48+
1549/**
1650 * Repository Type
1751 */
@@ -28,7 +62,7 @@ export function FilterCrudRepositoryMixin<
2862 Model extends Entity ,
2963 ModelID ,
3064 ModelRelations extends object = { }
31- > ( ) {
65+ > ( config : RepositoryConfig < Model , ModelID , ModelRelations > ) {
3266 /**
3367 * Return function with generic type of repository class, returns mixed in class
3468 *
@@ -50,25 +84,41 @@ export function FilterCrudRepositoryMixin<
5084
5185 class Repository extends parentClass
5286 implements FilterCrudRepository < Model , ModelID , ModelRelations > {
53- constructor ( ctor : Ctor < Model > , dataSource : juggler . DataSource ) {
87+ private application : Application ;
88+
89+ constructor (
90+ ctor : Ctor < Model > ,
91+ dataSource : juggler . DataSource ,
92+ application : Application
93+ ) {
5494 super ( ctor , dataSource ) ;
95+
96+ this . application = application ;
5597 }
5698
5799 /**
58- * Create methods
100+ * Get FilterContext method
59101 */
60- async create (
61- entity : DataObject < Model > ,
62- options ?: Options
63- ) : Promise < Model > {
64- return super . create ( entity , options ) ;
65- }
66-
67- async createAll (
68- entities : DataObject < Model > [ ] ,
69- options ?: Options
70- ) : Promise < Model [ ] > {
71- return super . createAll ( entities , options ) ;
102+ private getFilterContext (
103+ args : IArguments
104+ ) : FilterContext < Model , ModelID , ModelRelations > {
105+ return {
106+ target : this ,
107+ methodName : args . callee . name as any ,
108+ args : Array . from ( args ) ,
109+ invocationContext : new InvocationContext (
110+ this . application ,
111+ this . application . getSync (
112+ CoreBindings . CONTROLLER_CURRENT
113+ ) as any ,
114+ this . application . getSync (
115+ CoreBindings . CONTROLLER_METHOD_NAME
116+ ) ,
117+ this . application . getSync (
118+ CoreBindings . CONTROLLER_METHOD_META
119+ )
120+ ) ,
121+ } ;
72122 }
73123
74124 /**
@@ -78,82 +128,163 @@ export function FilterCrudRepositoryMixin<
78128 filter ?: Filter < Model > ,
79129 options ?: Options
80130 ) : Promise < ( Model & ModelRelations ) [ ] > {
81- return super . find ( filter , options ) ;
131+ const filterContext = this . getFilterContext ( arguments ) ;
132+
133+ return await super . find (
134+ {
135+ ...filter ,
136+ where : await config . where (
137+ filterContext ,
138+ filter ?. where || { }
139+ ) ,
140+ fields : await config . fields (
141+ filterContext ,
142+ filter ?. fields || { }
143+ ) ,
144+ } ,
145+ options
146+ ) ;
82147 }
83148
84149 async findOne (
85150 filter ?: Filter < Model > ,
86151 options ?: Options
87152 ) : Promise < ( Model & ModelRelations ) | null > {
88- return super . findOne ( filter , options ) ;
153+ const filterContext = this . getFilterContext ( arguments ) ;
154+
155+ return await super . findOne (
156+ {
157+ ...filter ,
158+ where : await config . where (
159+ filterContext ,
160+ filter ?. where || { }
161+ ) ,
162+ fields : await config . fields (
163+ filterContext ,
164+ filter ?. fields || { }
165+ ) ,
166+ } ,
167+ options
168+ ) ;
89169 }
90170
91171 async findById (
92172 id : ModelID ,
93173 filter ?: Filter < Model > ,
94174 options ?: Options
95175 ) : Promise < Model & ModelRelations > {
96- return super . findById ( id , filter , options ) ;
176+ const item = await this . findOne (
177+ {
178+ ...filter ,
179+ where : filter ?. where
180+ ? {
181+ and : [
182+ filter . where ,
183+ {
184+ [ config . id as any ] : id ,
185+ } ,
186+ ] ,
187+ }
188+ : {
189+ [ config . id as any ] : id ,
190+ } ,
191+ } ,
192+ options
193+ ) ;
194+
195+ if ( ! item ) {
196+ throw new EntityNotFoundError ( this . entityClass , id ) ;
197+ }
198+
199+ return item ;
97200 }
98201
99202 async count (
100203 where ?: Where < Model > ,
101204 options ?: Options
102205 ) : Promise < Count > {
103- return super . count ( where , options ) ;
206+ const filterContext = this . getFilterContext ( arguments ) ;
207+
208+ return await super . count (
209+ await config . where ( filterContext , where || { } ) ,
210+ options
211+ ) ;
104212 }
105213
106214 async exists ( id : ModelID , options ?: Options ) : Promise < boolean > {
107- return super . exists ( id , options ) ;
215+ const count = await this . count (
216+ { [ config . id as any ] : id } ,
217+ options
218+ ) ;
219+
220+ return count . count > 0 ;
108221 }
109222
110223 /**
111224 * Update methods
112225 */
113226 async update ( entity : Model , options ?: Options ) : Promise < void > {
114- return super . update ( entity , options ) ;
227+ await super . updateAll (
228+ entity ,
229+ { [ config . id as any ] : ( entity as any ) [ config . id ] } ,
230+ options
231+ ) ;
115232 }
116233
117234 async updateAll (
118235 data : DataObject < Model > ,
119236 where ?: Where < Model > ,
120237 options ?: Options
121238 ) : Promise < Count > {
122- return super . updateAll ( data , where , options ) ;
239+ const filterContext = this . getFilterContext ( arguments ) ;
240+
241+ return await super . updateAll (
242+ data ,
243+ await config . where ( filterContext , where || { } ) ,
244+ options
245+ ) ;
123246 }
124247
125248 async updateById (
126249 id : ModelID ,
127250 data : DataObject < Model > ,
128251 options ?: Options
129252 ) : Promise < void > {
130- return super . updateById ( id , data , options ) ;
253+ await this . updateAll ( data , { [ config . id as any ] : id } , options ) ;
131254 }
132255
133256 async replaceById (
134257 id : ModelID ,
135258 data : DataObject < Model > ,
136259 options ?: Options
137260 ) : Promise < void > {
138- return super . replaceById ( id , data , options ) ;
261+ await this . updateAll ( data , { [ config . id as any ] : id } , options ) ;
139262 }
140263
141264 /**
142265 * Delete methods
143266 */
144267 async delete ( entity : Model , options ?: Options ) : Promise < void > {
145- return super . delete ( entity , options ) ;
268+ await super . deleteAll (
269+ { [ config . id as any ] : ( entity as any ) [ config . id ] } ,
270+ options
271+ ) ;
146272 }
147273
148274 async deleteAll (
149275 where ?: Where < Model > ,
150276 options ?: Options
151277 ) : Promise < Count > {
152- return super . deleteAll ( where , options ) ;
278+ const filterContext = this . getFilterContext ( arguments ) ;
279+
280+ return await super . deleteAll (
281+ await config . where ( filterContext , where || { } ) ,
282+ options
283+ ) ;
153284 }
154285
155286 async deleteById ( id : ModelID , options ?: Options ) : Promise < void > {
156- return super . deleteById ( id , options ) ;
287+ await this . deleteAll ( { [ config . id as any ] : id } , options ) ;
157288 }
158289 }
159290
0 commit comments