Skip to content

Commit 1034200

Browse files
author
KoLiBer
committed
Merge branch 'release/0.1.0'
2 parents cd78a69 + 1a9518f commit 1034200

File tree

2 files changed

+170
-28
lines changed

2 files changed

+170
-28
lines changed

README.md

+12-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,19 @@ import { FilterCrudRepositoryMixin } from "loopback-component-filter";
3939

4040
export class UserRepository extends FilterCrudRepositoryMixin<
4141
User,
42+
string,
4243
UserRelations
43-
>(configs)() {
44+
>({
45+
id: "id",
46+
where: async (
47+
context,
48+
where
49+
) => where;
50+
fields: async (
51+
context,
52+
fields
53+
) => fields;
54+
})() {
4455
// ...
4556
}
4657
```

sources/src/repositories/filter.repository.ts

+158-27
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,51 @@
1+
import { InvocationArgs, InvocationContext } from "@loopback/context";
2+
import { Application, CoreBindings } from "@loopback/core";
13
import {
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

1317
import { 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

Comments
 (0)