@drax/crud-back 0.7.15 → 0.7.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/AbstractFastifyController.js +66 -0
- package/dist/repository/AbstractMongoRepository.js +21 -0
- package/dist/services/AbstractService.js +24 -1
- package/package.json +3 -3
- package/src/controllers/AbstractFastifyController.ts +69 -0
- package/src/repository/AbstractMongoRepository.ts +29 -0
- package/src/services/AbstractService.ts +31 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/AbstractFastifyController.d.ts +2 -0
- package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
- package/types/repository/AbstractMongoRepository.d.ts +2 -0
- package/types/repository/AbstractMongoRepository.d.ts.map +1 -1
- package/types/services/AbstractService.d.ts +3 -0
- package/types/services/AbstractService.d.ts.map +1 -1
|
@@ -196,6 +196,72 @@ class AbstractFastifyController {
|
|
|
196
196
|
}
|
|
197
197
|
}
|
|
198
198
|
}
|
|
199
|
+
async find(request, reply) {
|
|
200
|
+
var _a;
|
|
201
|
+
try {
|
|
202
|
+
request.rbac.assertPermission(this.permission.View);
|
|
203
|
+
if (!request.params.field || !request.params.value) {
|
|
204
|
+
reply.statusCode = 400;
|
|
205
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
206
|
+
}
|
|
207
|
+
const search = (_a = request.query).search ?? (_a.search = undefined);
|
|
208
|
+
const filters = this.parseFilters(request.query.filters);
|
|
209
|
+
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
210
|
+
let items = await this.service.find({ search, filters });
|
|
211
|
+
if (this.tenantAssert) {
|
|
212
|
+
items = items.filter(item => request.rbac.tenantId === item[this.tenantField].id);
|
|
213
|
+
}
|
|
214
|
+
return items;
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
console.error(e);
|
|
218
|
+
if (e instanceof ValidationError) {
|
|
219
|
+
reply.statusCode = e.statusCode;
|
|
220
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
221
|
+
}
|
|
222
|
+
else if (e instanceof UnauthorizedError) {
|
|
223
|
+
reply.statusCode = e.statusCode;
|
|
224
|
+
reply.send({ error: e.message });
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
reply.statusCode = 500;
|
|
228
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async findOne(request, reply) {
|
|
233
|
+
var _a;
|
|
234
|
+
try {
|
|
235
|
+
request.rbac.assertPermission(this.permission.View);
|
|
236
|
+
if (!request.params.field || !request.params.value) {
|
|
237
|
+
reply.statusCode = 400;
|
|
238
|
+
reply.send({ error: 'BAD REQUEST' });
|
|
239
|
+
}
|
|
240
|
+
const search = (_a = request.query).search ?? (_a.search = undefined);
|
|
241
|
+
const filters = this.parseFilters(request.query.filters);
|
|
242
|
+
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
243
|
+
let item = await this.service.findOne({ search, filters });
|
|
244
|
+
if (this.tenantAssert) {
|
|
245
|
+
request.rbac.assertTenantId(item[this.tenantField].id);
|
|
246
|
+
}
|
|
247
|
+
return item;
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
console.error(e);
|
|
251
|
+
if (e instanceof ValidationError) {
|
|
252
|
+
reply.statusCode = e.statusCode;
|
|
253
|
+
reply.send({ error: e.message, inputErrors: e.errors });
|
|
254
|
+
}
|
|
255
|
+
else if (e instanceof UnauthorizedError) {
|
|
256
|
+
reply.statusCode = e.statusCode;
|
|
257
|
+
reply.send({ error: e.message });
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
reply.statusCode = 500;
|
|
261
|
+
reply.send({ error: 'INTERNAL_SERVER_ERROR' });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
199
265
|
async findBy(request, reply) {
|
|
200
266
|
try {
|
|
201
267
|
request.rbac.assertPermission(this.permission.View);
|
|
@@ -33,6 +33,18 @@ class AbstractMongoRepository {
|
|
|
33
33
|
throw e;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
async updatePartial(id, data) {
|
|
37
|
+
try {
|
|
38
|
+
const item = await this._model.findOneAndUpdate({ _id: id }, data, { new: true }).populate(this._populateFields).exec();
|
|
39
|
+
return item;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (e instanceof mongoose.Error.ValidationError) {
|
|
43
|
+
throw MongooseErrorToValidationError(e);
|
|
44
|
+
}
|
|
45
|
+
throw e;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
36
48
|
async delete(id) {
|
|
37
49
|
const result = await this._model.deleteOne({ _id: id }).exec();
|
|
38
50
|
return result.deletedCount == 1;
|
|
@@ -85,6 +97,15 @@ class AbstractMongoRepository {
|
|
|
85
97
|
items: items.docs
|
|
86
98
|
};
|
|
87
99
|
}
|
|
100
|
+
async findOne({ search = '', filters = [] }) {
|
|
101
|
+
const query = {};
|
|
102
|
+
if (search) {
|
|
103
|
+
query['$or'] = this._searchFields.map(field => ({ [field]: new RegExp(search, 'i') }));
|
|
104
|
+
}
|
|
105
|
+
MongooseQueryFilter.applyFilters(query, filters);
|
|
106
|
+
const populate = this._populateFields;
|
|
107
|
+
return this._model.findOne(query).populate(populate);
|
|
108
|
+
}
|
|
88
109
|
async find({ limit = 0, orderBy = '', order = false, search = '', filters = [] }) {
|
|
89
110
|
const query = {};
|
|
90
111
|
if (search) {
|
|
@@ -45,6 +45,19 @@ class AbstractService {
|
|
|
45
45
|
throw e;
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
+
async updatePartial(id, data) {
|
|
49
|
+
try {
|
|
50
|
+
const item = await this._repository.updatePartial(id, data);
|
|
51
|
+
return item;
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
console.error("Error updating", e);
|
|
55
|
+
if (e instanceof ZodError) {
|
|
56
|
+
throw ZodErrorToValidationError(e, data);
|
|
57
|
+
}
|
|
58
|
+
throw e;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
48
61
|
async delete(id) {
|
|
49
62
|
try {
|
|
50
63
|
const result = await this._repository.delete(id);
|
|
@@ -155,7 +168,17 @@ class AbstractService {
|
|
|
155
168
|
return items;
|
|
156
169
|
}
|
|
157
170
|
catch (e) {
|
|
158
|
-
console.error("Error
|
|
171
|
+
console.error("Error find", e);
|
|
172
|
+
throw e;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async findOne({ search = '', filters = [] }) {
|
|
176
|
+
try {
|
|
177
|
+
let item = await this._repository.findOne({ search, filters });
|
|
178
|
+
return item;
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
console.error("Error findOne", e);
|
|
159
182
|
throw e;
|
|
160
183
|
}
|
|
161
184
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.7.
|
|
6
|
+
"version": "0.7.18",
|
|
7
7
|
"description": "Crud utils across modules",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"types": "types/index.d.ts",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@drax/common-back": "^0.7.0",
|
|
26
26
|
"@drax/common-share": "^0.7.0",
|
|
27
27
|
"@drax/identity-share": "^0.7.0",
|
|
28
|
-
"@drax/media-back": "^0.7.
|
|
28
|
+
"@drax/media-back": "^0.7.18",
|
|
29
29
|
"@graphql-tools/load-files": "^7.0.0",
|
|
30
30
|
"@graphql-tools/merge": "^9.0.4",
|
|
31
31
|
"mongoose": "^8.6.3",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"tsc-alias": "^1.8.10",
|
|
45
45
|
"typescript": "^5.6.2"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "c6bef958c68e2738724b77cc877e98108476c2a7"
|
|
48
48
|
}
|
|
@@ -241,6 +241,75 @@ class AbstractFastifyController<T, C, U> {
|
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
|
|
244
|
+
async find(request: CustomRequest, reply: FastifyReply):Promise<T[]> {
|
|
245
|
+
try {
|
|
246
|
+
request.rbac.assertPermission(this.permission.View)
|
|
247
|
+
if (!request.params.field || !request.params.value) {
|
|
248
|
+
reply.statusCode = 400
|
|
249
|
+
reply.send({error: 'BAD REQUEST'})
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const search = request.query.search ??= undefined
|
|
253
|
+
const filters = this.parseFilters(request.query.filters)
|
|
254
|
+
|
|
255
|
+
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
256
|
+
|
|
257
|
+
let items = await this.service.find({search,filters})
|
|
258
|
+
|
|
259
|
+
if (this.tenantAssert) {
|
|
260
|
+
items = items.filter(item => request.rbac.tenantId === item[this.tenantField].id)
|
|
261
|
+
}
|
|
262
|
+
return items
|
|
263
|
+
} catch (e) {
|
|
264
|
+
console.error(e)
|
|
265
|
+
if (e instanceof ValidationError) {
|
|
266
|
+
reply.statusCode = e.statusCode
|
|
267
|
+
reply.send({error: e.message, inputErrors: e.errors})
|
|
268
|
+
} else if (e instanceof UnauthorizedError) {
|
|
269
|
+
reply.statusCode = e.statusCode
|
|
270
|
+
reply.send({error: e.message})
|
|
271
|
+
} else {
|
|
272
|
+
reply.statusCode = 500
|
|
273
|
+
reply.send({error: 'INTERNAL_SERVER_ERROR'})
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async findOne(request: CustomRequest, reply: FastifyReply):Promise<T> {
|
|
279
|
+
try {
|
|
280
|
+
request.rbac.assertPermission(this.permission.View)
|
|
281
|
+
if (!request.params.field || !request.params.value) {
|
|
282
|
+
reply.statusCode = 400
|
|
283
|
+
reply.send({error: 'BAD REQUEST'})
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const search = request.query.search ??= undefined
|
|
287
|
+
const filters = this.parseFilters(request.query.filters)
|
|
288
|
+
|
|
289
|
+
this.applyUserAndTenantFilters(filters, request.rbac);
|
|
290
|
+
|
|
291
|
+
let item = await this.service.findOne({search,filters})
|
|
292
|
+
|
|
293
|
+
if (this.tenantAssert) {
|
|
294
|
+
request.rbac.assertTenantId(item[this.tenantField].id)
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
return item
|
|
298
|
+
} catch (e) {
|
|
299
|
+
console.error(e)
|
|
300
|
+
if (e instanceof ValidationError) {
|
|
301
|
+
reply.statusCode = e.statusCode
|
|
302
|
+
reply.send({error: e.message, inputErrors: e.errors})
|
|
303
|
+
} else if (e instanceof UnauthorizedError) {
|
|
304
|
+
reply.statusCode = e.statusCode
|
|
305
|
+
reply.send({error: e.message})
|
|
306
|
+
} else {
|
|
307
|
+
reply.statusCode = 500
|
|
308
|
+
reply.send({error: 'INTERNAL_SERVER_ERROR'})
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
244
313
|
async findBy(request: CustomRequest, reply: FastifyReply):Promise<T[]> {
|
|
245
314
|
try {
|
|
246
315
|
request.rbac.assertPermission(this.permission.View)
|
|
@@ -42,6 +42,18 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
async updatePartial(id: string, data: any): Promise<T> {
|
|
46
|
+
try {
|
|
47
|
+
const item: mongoose.HydratedDocument<T> = await this._model.findOneAndUpdate({_id: id}, data, {new: true}).populate(this._populateFields).exec()
|
|
48
|
+
return item
|
|
49
|
+
} catch (e) {
|
|
50
|
+
if (e instanceof mongoose.Error.ValidationError) {
|
|
51
|
+
throw MongooseErrorToValidationError(e)
|
|
52
|
+
}
|
|
53
|
+
throw e
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
45
57
|
async delete(id: string): Promise<boolean> {
|
|
46
58
|
const result: DeleteResult = await this._model.deleteOne({_id: id}).exec()
|
|
47
59
|
return result.deletedCount == 1
|
|
@@ -118,6 +130,23 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
|
|
|
118
130
|
}
|
|
119
131
|
}
|
|
120
132
|
|
|
133
|
+
async findOne({
|
|
134
|
+
search = '',
|
|
135
|
+
filters = []
|
|
136
|
+
}: IDraxFindOptions): Promise<T> {
|
|
137
|
+
|
|
138
|
+
const query = {}
|
|
139
|
+
|
|
140
|
+
if (search) {
|
|
141
|
+
query['$or'] = this._searchFields.map(field => ({[field]: new RegExp(search, 'i')}))
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
MongooseQueryFilter.applyFilters(query, filters)
|
|
145
|
+
|
|
146
|
+
const populate = this._populateFields
|
|
147
|
+
return this._model.findOne(query).populate(populate)
|
|
148
|
+
}
|
|
149
|
+
|
|
121
150
|
async find({
|
|
122
151
|
limit = 0,
|
|
123
152
|
orderBy = '',
|
|
@@ -12,6 +12,7 @@ import {IDraxCrudService} from "@drax/crud-share";
|
|
|
12
12
|
import ExportCsv from "../exports/ExportCsv.js";
|
|
13
13
|
import ExportJson from "../exports/ExportJson.js";
|
|
14
14
|
import {IDraxExportResult} from "@drax/crud-share";
|
|
15
|
+
import {IDraxFindOneOptions} from "@drax/crud-share/types/interfaces/IDraxFindOneOptions";
|
|
15
16
|
|
|
16
17
|
abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
17
18
|
|
|
@@ -69,6 +70,21 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
73
|
+
async updatePartial(id: string, data: any): Promise<T> {
|
|
74
|
+
try {
|
|
75
|
+
|
|
76
|
+
const item: T = await this._repository.updatePartial(id, data)
|
|
77
|
+
|
|
78
|
+
return item
|
|
79
|
+
} catch (e) {
|
|
80
|
+
console.error("Error updating", e)
|
|
81
|
+
if (e instanceof ZodError) {
|
|
82
|
+
throw ZodErrorToValidationError(e, data)
|
|
83
|
+
}
|
|
84
|
+
throw e
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
72
88
|
async delete(id: string): Promise<boolean> {
|
|
73
89
|
try {
|
|
74
90
|
const result: boolean = await this._repository.delete(id);
|
|
@@ -198,7 +214,21 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
198
214
|
let items = await this._repository.find({orderBy, order, search, filters});
|
|
199
215
|
return items;
|
|
200
216
|
} catch (e) {
|
|
201
|
-
console.error("Error
|
|
217
|
+
console.error("Error find", e)
|
|
218
|
+
throw e;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async findOne({
|
|
224
|
+
search = '',
|
|
225
|
+
filters = []
|
|
226
|
+
}: IDraxFindOneOptions): Promise<T> {
|
|
227
|
+
try {
|
|
228
|
+
let item = await this._repository.findOne({ search, filters});
|
|
229
|
+
return item;
|
|
230
|
+
} catch (e) {
|
|
231
|
+
console.error("Error findOne", e)
|
|
202
232
|
throw e;
|
|
203
233
|
}
|
|
204
234
|
|