@drax/crud-back 0.11.4 → 0.12.1

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.
Files changed (74) hide show
  1. package/dist/builders/CrudSchemaBuilder.js +349 -0
  2. package/dist/controllers/AbstractFastifyController.js +105 -176
  3. package/dist/index.js +15 -1
  4. package/dist/regexs/QueryFilterRegex.js +3 -0
  5. package/dist/repository/AbstractMongoRepository.js +114 -28
  6. package/dist/repository/AbstractSqliteRepository.js +131 -41
  7. package/dist/schemas/DeleteBodyResponseSchema.js +9 -0
  8. package/dist/schemas/ErrorBodyResponseSchema.js +16 -0
  9. package/dist/schemas/ExportBodyResponseSchema.js +9 -0
  10. package/dist/schemas/FindBySchema.js +6 -0
  11. package/dist/schemas/FindSchema.js +9 -0
  12. package/dist/schemas/IdParamSchema.js +6 -0
  13. package/dist/schemas/PaginateBodySchema.js +20 -0
  14. package/dist/schemas/PaginateSchema.js +17 -0
  15. package/dist/schemas/SearchSchema.js +5 -0
  16. package/dist/services/AbstractService.js +8 -5
  17. package/dist/zod/DeleteBodySchema.js +6 -0
  18. package/dist/zod/IdParamSchema.js +6 -0
  19. package/dist/zod/PaginateBodySchema.js +20 -0
  20. package/package.json +7 -6
  21. package/src/builders/CrudSchemaBuilder.ts +420 -0
  22. package/src/controllers/AbstractFastifyController.ts +149 -165
  23. package/src/index.ts +28 -0
  24. package/src/regexs/QueryFilterRegex.ts +4 -0
  25. package/src/repository/AbstractMongoRepository.ts +153 -40
  26. package/src/repository/AbstractSqliteRepository.ts +196 -72
  27. package/src/schemas/DeleteBodyResponseSchema.ts +12 -0
  28. package/src/schemas/ErrorBodyResponseSchema.ts +20 -0
  29. package/src/schemas/ExportBodyResponseSchema.ts +12 -0
  30. package/src/schemas/FindBySchema.ts +9 -0
  31. package/src/schemas/FindSchema.ts +13 -0
  32. package/src/schemas/IdParamSchema.ts +9 -0
  33. package/src/schemas/PaginateSchema.ts +21 -0
  34. package/src/schemas/SearchSchema.ts +8 -0
  35. package/src/services/AbstractService.ts +42 -33
  36. package/tsconfig.tsbuildinfo +1 -1
  37. package/types/builders/CrudSchemaBuilder.d.ts +2401 -0
  38. package/types/builders/CrudSchemaBuilder.d.ts.map +1 -0
  39. package/types/controllers/AbstractFastifyController.d.ts +6 -1
  40. package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
  41. package/types/index.d.ts +10 -1
  42. package/types/index.d.ts.map +1 -1
  43. package/types/regexs/QueryFilterRegex.d.ts +4 -0
  44. package/types/regexs/QueryFilterRegex.d.ts.map +1 -0
  45. package/types/repository/AbstractMongoRepository.d.ts +6 -3
  46. package/types/repository/AbstractMongoRepository.d.ts.map +1 -1
  47. package/types/repository/AbstractSqliteRepository.d.ts +23 -8
  48. package/types/repository/AbstractSqliteRepository.d.ts.map +1 -1
  49. package/types/schemas/DeleteBodyResponseSchema.d.ts +20 -0
  50. package/types/schemas/DeleteBodyResponseSchema.d.ts.map +1 -0
  51. package/types/schemas/ErrorBodyResponseSchema.d.ts +60 -0
  52. package/types/schemas/ErrorBodyResponseSchema.d.ts.map +1 -0
  53. package/types/schemas/ExportBodyResponseSchema.d.ts +20 -0
  54. package/types/schemas/ExportBodyResponseSchema.d.ts.map +1 -0
  55. package/types/schemas/FindBySchema.d.ts +13 -0
  56. package/types/schemas/FindBySchema.d.ts.map +1 -0
  57. package/types/schemas/FindSchema.d.ts +19 -0
  58. package/types/schemas/FindSchema.d.ts.map +1 -0
  59. package/types/schemas/IdParamSchema.d.ts +11 -0
  60. package/types/schemas/IdParamSchema.d.ts.map +1 -0
  61. package/types/schemas/PaginateBodySchema.d.ts +61 -0
  62. package/types/schemas/PaginateBodySchema.d.ts.map +1 -0
  63. package/types/schemas/PaginateSchema.d.ts +41 -0
  64. package/types/schemas/PaginateSchema.d.ts.map +1 -0
  65. package/types/schemas/SearchSchema.d.ts +10 -0
  66. package/types/schemas/SearchSchema.d.ts.map +1 -0
  67. package/types/services/AbstractService.d.ts +5 -5
  68. package/types/services/AbstractService.d.ts.map +1 -1
  69. package/types/zod/DeleteBodySchema.d.ts +11 -0
  70. package/types/zod/DeleteBodySchema.d.ts.map +1 -0
  71. package/types/zod/IdParamSchema.d.ts +11 -0
  72. package/types/zod/IdParamSchema.d.ts.map +1 -0
  73. package/types/zod/PaginateBodySchema.d.ts +61 -0
  74. package/types/zod/PaginateBodySchema.d.ts.map +1 -0
@@ -1,10 +1,23 @@
1
1
  import AbstractService from "../services/AbstractService";
2
- import {CommonConfig, DraxConfig, ValidationError} from "@drax/common-back";
2
+ import {
3
+ CommonConfig,
4
+ DraxConfig,
5
+ ForbiddenError,
6
+ InternalServerError,
7
+ InvalidIdError,
8
+ LimitError,
9
+ NotFoundError,
10
+ ValidationError,
11
+ SecuritySensitiveError,
12
+ UploadFileError,
13
+ BadRequestError
14
+ } from "@drax/common-back";
3
15
  import {UnauthorizedError} from "@drax/common-back";
4
16
  import {IRbac} from "@drax/identity-share";
5
17
  import type {FastifyReply, FastifyRequest} from "fastify";
6
18
  import {IDraxExportResult, IDraxPermission, IDraxFieldFilter} from "@drax/crud-share";
7
19
  import {join} from "path";
20
+ import QueryFilterRegex from "../regexs/QueryFilterRegex.js";
8
21
 
9
22
  declare module 'fastify' {
10
23
  interface FastifyRequest {
@@ -25,7 +38,7 @@ type CustomRequest = FastifyRequest<{
25
38
  page?: number
26
39
  limit?: number
27
40
  orderBy?: string
28
- order?: 'asc' | 'desc' | boolean
41
+ order?: 'asc' | 'desc'
29
42
  search?: string
30
43
  filters?: string
31
44
  headers?: string
@@ -54,6 +67,9 @@ class AbstractFastifyController<T, C, U> {
54
67
  protected tenantAssert: boolean = false
55
68
  protected userAssert: boolean = false
56
69
 
70
+ protected defaultLimit: number = 1000
71
+ protected maximumLimit: number = 10000
72
+
57
73
  constructor(service: AbstractService<T, C, U>, permission: IDraxPermission) {
58
74
  this.service = service
59
75
  this.permission = permission
@@ -65,6 +81,11 @@ class AbstractFastifyController<T, C, U> {
65
81
  if (!stringFilters) {
66
82
  return []
67
83
  }
84
+
85
+ if (!QueryFilterRegex.test(stringFilters)) {
86
+ throw new BadRequestError("Invalid filters format")
87
+ }
88
+
68
89
  const filterArray = stringFilters.split("|")
69
90
  const filters: IDraxFieldFilter[] = []
70
91
  filterArray.forEach((filter) => {
@@ -73,12 +94,12 @@ class AbstractFastifyController<T, C, U> {
73
94
  })
74
95
  return filters
75
96
  } catch (e) {
76
- console.error(e)
97
+ console.error("parseFilters error",e)
77
98
  throw e
78
99
  }
79
100
  }
80
101
 
81
- private applyUserAndTenantFilters(filters: IDraxFieldFilter[], rbac: any) {
102
+ private applyUserAndTenantFilters(filters: IDraxFieldFilter[], rbac: IRbac) {
82
103
  if (this.tenantFilter && rbac.tenantId) {
83
104
  filters.push({field: this.tenantField, operator: 'eq', value: rbac.tenantId})
84
105
  }
@@ -88,6 +109,18 @@ class AbstractFastifyController<T, C, U> {
88
109
  }
89
110
  }
90
111
 
112
+ private assertUserAndTenant(item: T, rbac: IRbac) {
113
+ if (this.tenantAssert) {
114
+ const itemTenantId = item[this.tenantField] && item[this.tenantField]._id ? item[this.tenantField]._id : null
115
+ rbac.assertTenantId(itemTenantId)
116
+ }
117
+
118
+ if (this.userAssert) {
119
+ const itemUserId = item[this.userField] && item[this.userField]._id ? item[this.userField]._id : null
120
+ rbac.assertUserId(itemUserId)
121
+ }
122
+ }
123
+
91
124
  private applyUserAndTenantSetters(payload: any, rbac: any) {
92
125
  if (this.tenantSetter && rbac.tenantId) {
93
126
  payload[this.tenantField] = rbac.tenantId
@@ -98,6 +131,28 @@ class AbstractFastifyController<T, C, U> {
98
131
  }
99
132
  }
100
133
 
134
+ handleError(e: unknown, reply: FastifyReply) {
135
+ console.error(e);
136
+
137
+ if (
138
+ e instanceof ValidationError ||
139
+ e instanceof NotFoundError ||
140
+ e instanceof BadRequestError ||
141
+ e instanceof UnauthorizedError ||
142
+ e instanceof ForbiddenError ||
143
+ e instanceof InvalidIdError ||
144
+ e instanceof SecuritySensitiveError ||
145
+ e instanceof UploadFileError ||
146
+ e instanceof LimitError
147
+ ) {
148
+ reply.status(e.statusCode).send(e.body);
149
+ } else {
150
+ const serverError = new InternalServerError()
151
+ reply.statusCode = serverError.statusCode
152
+ reply.status(500).send(serverError.body);
153
+ }
154
+ }
155
+
101
156
  async create(request: CustomRequest, reply: FastifyReply) {
102
157
  try {
103
158
  request.rbac.assertPermission(this.permission.Create)
@@ -106,17 +161,7 @@ class AbstractFastifyController<T, C, U> {
106
161
  let item = await this.service.create(payload as C)
107
162
  return item
108
163
  } catch (e) {
109
- console.error(e)
110
- if (e instanceof ValidationError) {
111
- reply.statusCode = e.statusCode
112
- reply.send({error: e.message, inputErrors: e.errors})
113
- } else if (e instanceof UnauthorizedError) {
114
- reply.statusCode = e.statusCode
115
- reply.send({error: e.message})
116
- } else {
117
- reply.statusCode = 500
118
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
119
- }
164
+ this.handleError(e, reply)
120
165
  }
121
166
  }
122
167
 
@@ -131,19 +176,34 @@ class AbstractFastifyController<T, C, U> {
131
176
  const payload = request.body
132
177
  //this.applyUserAndTenantSetters(payload, request.rbac)
133
178
  let item = await this.service.update(id, payload as U)
179
+
180
+ if (!item) {
181
+ throw new NotFoundError()
182
+ }
183
+
134
184
  return item
135
185
  } catch (e) {
136
- console.error(e)
137
- if (e instanceof ValidationError) {
138
- reply.statusCode = e.statusCode
139
- reply.send({error: e.message, inputErrors: e.errors})
140
- } else if (e instanceof UnauthorizedError) {
141
- reply.statusCode = e.statusCode
142
- reply.send({error: e.message})
143
- } else {
144
- reply.statusCode = 500
145
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
186
+ this.handleError(e, reply)
187
+ }
188
+ }
189
+
190
+ async updatePartial(request: CustomRequest, reply: FastifyReply) {
191
+ try {
192
+ request.rbac.assertPermission(this.permission.Update)
193
+ if (!request.params.id) {
194
+ reply.statusCode = 400
195
+ reply.send({error: 'BAD REQUEST'})
146
196
  }
197
+ const id = request.params.id
198
+ const payload = request.body
199
+ //this.applyUserAndTenantSetters(payload, request.rbac)
200
+ let item = await this.service.updatePartial(id, payload as U)
201
+ if (!item) {
202
+ throw new NotFoundError()
203
+ }
204
+ return item
205
+ } catch (e) {
206
+ this.handleError(e, reply)
147
207
  }
148
208
  }
149
209
 
@@ -158,33 +218,29 @@ class AbstractFastifyController<T, C, U> {
158
218
 
159
219
  let item = await this.service.findById(id)
160
220
 
161
- if(!item) {
221
+ if (!item) {
162
222
  reply.statusCode = 404
163
223
  reply.send({error: 'NOT_FOUND'})
164
224
  }
165
225
 
166
226
  if (this.tenantAssert) {
167
- request.rbac.assertTenantId(item[this.tenantField].id)
227
+ const tenantId = item[this.tenantField] && item[this.tenantField]._id ? item[this.tenantField]._id : null
228
+ request.rbac.assertTenantId(tenantId)
168
229
  }
169
230
 
170
231
  await this.service.delete(id)
171
- reply.send({message: 'Item deleted successfully'})
232
+ reply.send({
233
+ id: id,
234
+ message: 'Item deleted successfully',
235
+ deleted: true,
236
+ deletedAt: new Date(),
237
+ })
172
238
  } catch (e) {
173
- console.error(e)
174
- if (e instanceof ValidationError) {
175
- reply.statusCode = e.statusCode
176
- reply.send({error: e.message, inputErrors: e.errors})
177
- } else if (e instanceof UnauthorizedError) {
178
- reply.statusCode = e.statusCode
179
- reply.send({error: e.message})
180
- } else {
181
- reply.statusCode = 500
182
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
183
- }
239
+ this.handleError(e, reply)
184
240
  }
185
241
  }
186
242
 
187
- async findById(request: CustomRequest, reply: FastifyReply) : Promise<T> {
243
+ async findById(request: CustomRequest, reply: FastifyReply): Promise<T> {
188
244
  try {
189
245
  request.rbac.assertPermission(this.permission.View)
190
246
  if (!request.params.id) {
@@ -196,27 +252,22 @@ class AbstractFastifyController<T, C, U> {
196
252
  const id = request.params.id
197
253
  let item = await this.service.findById(id)
198
254
 
255
+ if (!item) {
256
+ throw new NotFoundError()
257
+ }
258
+
199
259
  if (this.tenantAssert) {
200
- request.rbac.assertTenantId(item[this.tenantField].id)
260
+ const itemTenantId = item[this.tenantField] && item[this.tenantField]._id? item[this.tenantField]._id : null
261
+ request.rbac.assertTenantId(itemTenantId)
201
262
  }
202
263
 
203
264
  return item
204
265
  } catch (e) {
205
- console.error(e)
206
- if (e instanceof ValidationError) {
207
- reply.statusCode = e.statusCode
208
- reply.send({error: e.message, inputErrors: e.errors})
209
- } else if (e instanceof UnauthorizedError) {
210
- reply.statusCode = e.statusCode
211
- reply.send({error: e.message})
212
- } else {
213
- reply.statusCode = 500
214
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
215
- }
266
+ this.handleError(e, reply)
216
267
  }
217
268
  }
218
269
 
219
- async findByIds(request: CustomRequest, reply: FastifyReply):Promise<T[]> {
270
+ async findByIds(request: CustomRequest, reply: FastifyReply): Promise<T[]> {
220
271
  try {
221
272
  request.rbac.assertPermission(this.permission.View)
222
273
  if (!request.params.ids) {
@@ -225,53 +276,42 @@ class AbstractFastifyController<T, C, U> {
225
276
  }
226
277
  const ids = request.params.ids.split(",")
227
278
  let items = await this.service.findByIds(ids)
279
+
280
+ if (!items || items.length === 0) {
281
+ throw new NotFoundError()
282
+ }
283
+
228
284
  return items
229
285
  } catch (e) {
230
- console.error(e)
231
- if (e instanceof ValidationError) {
232
- reply.statusCode = e.statusCode
233
- reply.send({error: e.message, inputErrors: e.errors})
234
- } else if (e instanceof UnauthorizedError) {
235
- reply.statusCode = e.statusCode
236
- reply.send({error: e.message})
237
- } else {
238
- reply.statusCode = 500
239
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
240
- }
286
+ this.handleError(e, reply)
241
287
  }
242
288
  }
243
289
 
244
- async find(request: CustomRequest, reply: FastifyReply):Promise<T[]> {
290
+ async find(request: CustomRequest, reply: FastifyReply): Promise<T[]> {
245
291
  try {
246
292
  request.rbac.assertPermission(this.permission.View)
247
293
 
294
+ if (request.query.limit > this.maximumLimit) {
295
+ throw new LimitError(this.maximumLimit, request.query.limit)
296
+ }
297
+ const limit = request.query.limit ? request.query.limit : this.defaultLimit
298
+ const orderBy = request.query.orderBy
299
+ const order = request.query.order
248
300
  const search = request.query.search ??= undefined
249
301
  const filters = this.parseFilters(request.query.filters)
250
302
 
251
303
  this.applyUserAndTenantFilters(filters, request.rbac);
252
304
 
253
- let items = await this.service.find({search,filters})
305
+ let items = await this.service.find({search, filters, order, orderBy, limit})
306
+
254
307
 
255
- if (this.tenantAssert) {
256
- items = items.filter(item => request.rbac.tenantId === item[this.tenantField].id)
257
- }
258
308
  return items
259
309
  } catch (e) {
260
- console.error(e)
261
- if (e instanceof ValidationError) {
262
- reply.statusCode = e.statusCode
263
- reply.send({error: e.message, inputErrors: e.errors})
264
- } else if (e instanceof UnauthorizedError) {
265
- reply.statusCode = e.statusCode
266
- reply.send({error: e.message})
267
- } else {
268
- reply.statusCode = 500
269
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
270
- }
310
+ this.handleError(e, reply)
271
311
  }
272
312
  }
273
313
 
274
- async findOne(request: CustomRequest, reply: FastifyReply):Promise<T> {
314
+ async findOne(request: CustomRequest, reply: FastifyReply): Promise<T> {
275
315
  try {
276
316
  request.rbac.assertPermission(this.permission.View)
277
317
 
@@ -280,29 +320,16 @@ class AbstractFastifyController<T, C, U> {
280
320
 
281
321
  this.applyUserAndTenantFilters(filters, request.rbac);
282
322
 
283
- let item = await this.service.findOne({search,filters})
323
+ let item = await this.service.findOne({search, filters})
284
324
 
285
- if (this.tenantAssert) {
286
- request.rbac.assertTenantId(item[this.tenantField].id)
287
- }
288
325
 
289
326
  return item
290
327
  } catch (e) {
291
- console.error(e)
292
- if (e instanceof ValidationError) {
293
- reply.statusCode = e.statusCode
294
- reply.send({error: e.message, inputErrors: e.errors})
295
- } else if (e instanceof UnauthorizedError) {
296
- reply.statusCode = e.statusCode
297
- reply.send({error: e.message})
298
- } else {
299
- reply.statusCode = 500
300
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
301
- }
328
+ this.handleError(e, reply)
302
329
  }
303
330
  }
304
331
 
305
- async findBy(request: CustomRequest, reply: FastifyReply):Promise<T[]> {
332
+ async findBy(request: CustomRequest, reply: FastifyReply): Promise<T[]> {
306
333
  try {
307
334
  request.rbac.assertPermission(this.permission.View)
308
335
  if (!request.params.field || !request.params.value) {
@@ -310,30 +337,22 @@ class AbstractFastifyController<T, C, U> {
310
337
  reply.send({error: 'BAD REQUEST'})
311
338
  }
312
339
 
340
+ const limit = this.defaultLimit
313
341
  const field = request.params.field
314
342
  const value = request.params.value
315
- let items = await this.service.findBy(field,value)
343
+ let items = await this.service.findBy(field, value, limit)
316
344
 
317
- if (this.tenantAssert) {
318
- items = items.filter(item => request.rbac.tenantId === item[this.tenantField].id)
345
+ for (let item of items) {
346
+ this.assertUserAndTenant(item, request.rbac)
319
347
  }
348
+
320
349
  return items
321
350
  } catch (e) {
322
- console.error(e)
323
- if (e instanceof ValidationError) {
324
- reply.statusCode = e.statusCode
325
- reply.send({error: e.message, inputErrors: e.errors})
326
- } else if (e instanceof UnauthorizedError) {
327
- reply.statusCode = e.statusCode
328
- reply.send({error: e.message})
329
- } else {
330
- reply.statusCode = 500
331
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
332
- }
351
+ this.handleError(e, reply)
333
352
  }
334
353
  }
335
354
 
336
- async findOneBy(request: CustomRequest, reply: FastifyReply):Promise<T> {
355
+ async findOneBy(request: CustomRequest, reply: FastifyReply): Promise<T> {
337
356
  try {
338
357
  request.rbac.assertPermission(this.permission.View)
339
358
  if (!request.params.field || !request.params.value) {
@@ -343,59 +362,44 @@ class AbstractFastifyController<T, C, U> {
343
362
 
344
363
  const field = request.params.field
345
364
  const value = request.params.value
346
- let item = await this.service.findOneBy(field,value)
347
-
348
- if (this.tenantAssert) {
349
- request.rbac.assertTenantId(item[this.tenantField].id)
350
- }
365
+ let item = await this.service.findOneBy(field, value)
366
+ this.assertUserAndTenant(item, request.rbac);
351
367
 
352
368
  return item
353
369
  } catch (e) {
354
- console.error(e)
355
- if (e instanceof ValidationError) {
356
- reply.statusCode = e.statusCode
357
- reply.send({error: e.message, inputErrors: e.errors})
358
- } else if (e instanceof UnauthorizedError) {
359
- reply.statusCode = e.statusCode
360
- reply.send({error: e.message})
361
- } else {
362
- reply.statusCode = 500
363
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
364
- }
370
+ this.handleError(e, reply)
365
371
  }
366
372
  }
367
373
 
374
+
375
+
368
376
  async search(request: CustomRequest, reply: FastifyReply) {
369
377
  try {
370
378
  request.rbac.assertPermission(this.permission.View)
371
379
  const search = request.query.search
372
- const limit = 1000;
373
- const filters = this.parseFilters(request.query.filters)
380
+ const filters = []
381
+ const limit = this.defaultLimit
374
382
 
375
383
  this.applyUserAndTenantFilters(filters, request.rbac);
376
384
 
377
385
  let item = await this.service.search(search, limit, filters)
378
386
  return item
379
387
  } catch (e) {
380
- console.error(e)
381
- if (e instanceof ValidationError) {
382
- reply.statusCode = e.statusCode
383
- reply.send({error: e.message, inputErrors: e.errors})
384
- } else if (e instanceof UnauthorizedError) {
385
- reply.statusCode = e.statusCode
386
- reply.send({error: e.message})
387
- } else {
388
- reply.statusCode = 500
389
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
390
- }
388
+ this.handleError(e, reply)
391
389
  }
392
390
  }
393
391
 
394
392
  async paginate(request: CustomRequest, reply: FastifyReply) {
395
393
  try {
396
394
  request.rbac.assertPermission(this.permission.View)
397
- const page = request.query.page
398
- const limit = request.query.limit
395
+
396
+
397
+ if (request.query.limit > this.maximumLimit) {
398
+ throw new LimitError(this.maximumLimit, request.query.limit)
399
+ }
400
+
401
+ const page = request.query.page ? request.query.page : 1
402
+ const limit = request.query.limit ? request.query.limit : 10
399
403
  const orderBy = request.query.orderBy
400
404
  const order = request.query.order
401
405
  const search = request.query.search
@@ -407,17 +411,7 @@ class AbstractFastifyController<T, C, U> {
407
411
  let paginateResult = await this.service.paginate({page, limit, orderBy, order, search, filters})
408
412
  return paginateResult
409
413
  } catch (e) {
410
- console.error(e)
411
- if (e instanceof ValidationError) {
412
- reply.statusCode = e.statusCode
413
- reply.send({error: e.message, inputErrors: e.errors})
414
- } else if (e instanceof UnauthorizedError) {
415
- reply.statusCode = e.statusCode
416
- reply.send({error: e.message})
417
- } else {
418
- reply.statusCode = 500
419
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
420
- }
414
+ this.handleError(e, reply)
421
415
  }
422
416
  }
423
417
 
@@ -465,17 +459,7 @@ class AbstractFastifyController<T, C, U> {
465
459
  }
466
460
 
467
461
  } catch (e) {
468
- console.error(e)
469
- if (e instanceof ValidationError) {
470
- reply.statusCode = e.statusCode
471
- reply.send({error: e.message, inputErrors: e.errors})
472
- } else if (e instanceof UnauthorizedError) {
473
- reply.statusCode = e.statusCode
474
- reply.send({error: e.message})
475
- } else {
476
- reply.statusCode = 500
477
- reply.send({error: 'INTERNAL_SERVER_ERROR'})
478
- }
462
+ this.handleError(e, reply)
479
463
  }
480
464
  }
481
465
  }
package/src/index.ts CHANGED
@@ -4,6 +4,17 @@ import AbstractSqliteRepository from "./repository/AbstractSqliteRepository.js";
4
4
  import AbstractService from "./services/AbstractService.js";
5
5
  import AbstractFastifyController from "./controllers/AbstractFastifyController.js";
6
6
 
7
+ //schemas
8
+ import {IdParamSchema} from "./schemas/IdParamSchema.js"
9
+ import {DeleteBodyResponseSchema} from "./schemas/DeleteBodyResponseSchema.js"
10
+ import {PaginateBodyResponseSchema, PaginateQuerySchema} from "./schemas/PaginateSchema.js"
11
+ import {FindQuerySchema} from "./schemas/FindSchema.js"
12
+ import {SearchQuerySchema} from "./schemas/SearchSchema.js"
13
+ import {FindByParamSchema} from "./schemas/FindBySchema.js"
14
+ import {ExportBodyResponseSchema} from "./schemas/ExportBodyResponseSchema.js"
15
+ import {ErrorBodyResponseSchema, ValidationErrorBodyResponseSchema} from "./schemas/ErrorBodyResponseSchema.js"
16
+ import {CrudSchemaBuilder} from "./builders/CrudSchemaBuilder.js";
17
+
7
18
 
8
19
  export {
9
20
 
@@ -13,4 +24,21 @@ export {
13
24
  AbstractService,
14
25
  AbstractFastifyController,
15
26
 
27
+
28
+ //Schemas
29
+ IdParamSchema,
30
+ DeleteBodyResponseSchema,
31
+ PaginateBodyResponseSchema,
32
+ PaginateQuerySchema,
33
+ FindQuerySchema,
34
+ SearchQuerySchema,
35
+ FindByParamSchema,
36
+ ErrorBodyResponseSchema,
37
+ ValidationErrorBodyResponseSchema,
38
+ ExportBodyResponseSchema,
39
+
40
+ //Builder
41
+ CrudSchemaBuilder,
42
+
43
+
16
44
  }
@@ -0,0 +1,4 @@
1
+ const QueryFilterRegex = /^(?:[a-zA-Z0-9_]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_]+)(?:\|[a-zA-Z0-9_]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_]+)*$/
2
+
3
+ export default QueryFilterRegex
4
+ export {QueryFilterRegex}