@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.
@@ -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 paginating", e);
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.15",
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.15",
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": "d1b96ce648f538b1b70bd9cecbdbfc1dc39b282a"
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 paginating", e)
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