@drax/crud-back 1.1.0 → 1.3.0
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/repository/AbstractMongoRepository.js +1 -1
- package/dist/services/AbstractService.js +150 -86
- package/package.json +4 -4
- package/src/repository/AbstractMongoRepository.ts +1 -1
- package/src/services/AbstractService.ts +199 -94
- package/tsconfig.tsbuildinfo +1 -1
- package/types/services/AbstractService.d.ts +10 -4
- package/types/services/AbstractService.d.ts.map +1 -1
|
@@ -17,8 +17,10 @@ import {IDraxFindOneOptions} from "@drax/crud-share/types/interfaces/IDraxFindOn
|
|
|
17
17
|
abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
18
18
|
|
|
19
19
|
protected _repository: IDraxCrudRepository<T, C, U>
|
|
20
|
-
protected
|
|
20
|
+
protected _baseSchema?: ZodObject<ZodRawShape> | undefined
|
|
21
|
+
protected _fullSchema?: ZodObject<ZodRawShape> | undefined
|
|
21
22
|
protected _defaultOrder?: string | undefined
|
|
23
|
+
protected _validateOutput: boolean = true
|
|
22
24
|
|
|
23
25
|
transformCreate?: (data: C) => Promise<C>;
|
|
24
26
|
transformUpdate?: (data: U) => Promise<U>;
|
|
@@ -29,88 +31,139 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
29
31
|
onDeleted?: (id: string) => Promise<void>;
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
constructor(repository: IDraxCrudRepository<T, C, U>, schema?: ZodObject<ZodRawShape>) {
|
|
34
|
+
constructor(repository: IDraxCrudRepository<T, C, U>, baseSchema?: ZodObject<ZodRawShape>, fullSchema?: ZodObject<ZodRawShape>) {
|
|
34
35
|
this._repository = repository
|
|
35
|
-
this.
|
|
36
|
+
this._baseSchema = baseSchema
|
|
37
|
+
this._fullSchema = fullSchema
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
async validateInputCreate(data: C): Promise<C> {
|
|
41
|
+
if (this._baseSchema) {
|
|
42
|
+
try {
|
|
43
|
+
return await this._baseSchema.parseAsync(data) as C
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.error("Error on validateInput", {
|
|
46
|
+
name: e?.name,
|
|
47
|
+
message: e?.message,
|
|
48
|
+
stack: e?.stack,
|
|
49
|
+
});
|
|
50
|
+
if (e instanceof ZodError) {
|
|
51
|
+
throw ZodErrorToValidationError(e, data)
|
|
52
|
+
}
|
|
53
|
+
throw e
|
|
43
54
|
}
|
|
44
|
-
|
|
45
|
-
|
|
55
|
+
}
|
|
56
|
+
return data
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async validateInputUpdate(data: U): Promise<U> {
|
|
60
|
+
if (this._baseSchema) {
|
|
61
|
+
try {
|
|
62
|
+
return await this._baseSchema.parseAsync(data) as U
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error("Error on validateInput", {
|
|
65
|
+
name: e?.name,
|
|
66
|
+
message: e?.message,
|
|
67
|
+
stack: e?.stack,
|
|
68
|
+
});
|
|
69
|
+
if (e instanceof ZodError) {
|
|
70
|
+
throw ZodErrorToValidationError(e, data)
|
|
71
|
+
}
|
|
72
|
+
throw e
|
|
46
73
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
74
|
+
}
|
|
75
|
+
return data
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async validateInputUpdatePartial(data: U): Promise<U> {
|
|
79
|
+
if (this._baseSchema) {
|
|
80
|
+
try {
|
|
81
|
+
return await this._baseSchema.partial().parseAsync(data) as U
|
|
82
|
+
} catch (e) {
|
|
83
|
+
console.error("Error on validateInput", {
|
|
84
|
+
name: e?.name,
|
|
85
|
+
message: e?.message,
|
|
86
|
+
stack: e?.stack,
|
|
87
|
+
});
|
|
88
|
+
if (e instanceof ZodError) {
|
|
89
|
+
throw ZodErrorToValidationError(e, data)
|
|
90
|
+
}
|
|
91
|
+
throw e
|
|
50
92
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
93
|
+
}
|
|
94
|
+
return data
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async validateOutput(item: T): Promise<T> {
|
|
98
|
+
if (this._validateOutput && item && this._fullSchema) {
|
|
99
|
+
try {
|
|
100
|
+
return await this._fullSchema.parseAsync(item) as T
|
|
101
|
+
} catch (e) {
|
|
102
|
+
console.error("Error on validateOutput", {
|
|
103
|
+
name: e?.name,
|
|
104
|
+
message: e?.message,
|
|
105
|
+
stack: e?.stack,
|
|
106
|
+
});
|
|
107
|
+
throw e
|
|
60
108
|
}
|
|
61
|
-
throw e
|
|
62
109
|
}
|
|
110
|
+
return item
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async create(data: C): Promise<T> {
|
|
114
|
+
|
|
115
|
+
data = await this.validateInputCreate(data)
|
|
116
|
+
|
|
117
|
+
if (this.transformCreate) {
|
|
118
|
+
data = await this.transformCreate(data)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let item: T = await this._repository.create(data)
|
|
122
|
+
|
|
123
|
+
if (this.onCreated) {
|
|
124
|
+
await this.onCreated(item)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
item = await this.validateOutput(item)
|
|
128
|
+
|
|
129
|
+
return item
|
|
130
|
+
|
|
63
131
|
}
|
|
64
132
|
|
|
65
133
|
async update(id: string, data: U): Promise<T> {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
data = await this.transformUpdate(data)
|
|
72
|
-
}
|
|
73
|
-
const item: T = await this._repository.update(id, data)
|
|
74
|
-
if (this.onUpdated) {
|
|
75
|
-
await this.onUpdated(item)
|
|
76
|
-
}
|
|
77
|
-
return item
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.error("Error update", {
|
|
80
|
-
name: e?.name,
|
|
81
|
-
message: e?.message,
|
|
82
|
-
stack: e?.stack,
|
|
83
|
-
});
|
|
84
|
-
if (e instanceof ZodError) {
|
|
85
|
-
throw ZodErrorToValidationError(e, data)
|
|
86
|
-
}
|
|
87
|
-
throw e
|
|
134
|
+
|
|
135
|
+
data = await this.validateInputUpdate(data)
|
|
136
|
+
|
|
137
|
+
if (this.transformUpdate) {
|
|
138
|
+
data = await this.transformUpdate(data)
|
|
88
139
|
}
|
|
140
|
+
|
|
141
|
+
let item: T = await this._repository.update(id, data)
|
|
142
|
+
|
|
143
|
+
if (this.onUpdated) {
|
|
144
|
+
await this.onUpdated(item)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
item = await this.validateOutput(item)
|
|
148
|
+
|
|
149
|
+
return item
|
|
150
|
+
|
|
89
151
|
}
|
|
90
152
|
|
|
91
153
|
async updatePartial(id: string, data: any): Promise<T> {
|
|
92
|
-
try {
|
|
93
154
|
|
|
94
|
-
|
|
95
|
-
data = await this._schema.partial().parseAsync(data)
|
|
96
|
-
}
|
|
155
|
+
data = await this.validateInputUpdatePartial(data)
|
|
97
156
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return item
|
|
103
|
-
} catch (e) {
|
|
104
|
-
console.error("Error updatePartial", {
|
|
105
|
-
name: e?.name,
|
|
106
|
-
message: e?.message,
|
|
107
|
-
stack: e?.stack,
|
|
108
|
-
});
|
|
109
|
-
if (e instanceof ZodError) {
|
|
110
|
-
throw ZodErrorToValidationError(e, data)
|
|
111
|
-
}
|
|
112
|
-
throw e
|
|
157
|
+
let item: T = await this._repository.updatePartial(id, data)
|
|
158
|
+
|
|
159
|
+
if (this.onUpdated) {
|
|
160
|
+
await this.onUpdated(item)
|
|
113
161
|
}
|
|
162
|
+
|
|
163
|
+
item = await this.validateOutput(item)
|
|
164
|
+
|
|
165
|
+
return item
|
|
166
|
+
|
|
114
167
|
}
|
|
115
168
|
|
|
116
169
|
async delete(id: string): Promise<boolean> {
|
|
@@ -119,7 +172,7 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
119
172
|
if (!result) {
|
|
120
173
|
throw new Error("error.deletionFailed");
|
|
121
174
|
}
|
|
122
|
-
if(this.onDeleted) {
|
|
175
|
+
if (this.onDeleted) {
|
|
123
176
|
await this.onDeleted(id)
|
|
124
177
|
}
|
|
125
178
|
return result;
|
|
@@ -136,11 +189,17 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
136
189
|
|
|
137
190
|
async findById(id: string): Promise<T | null> {
|
|
138
191
|
try {
|
|
139
|
-
|
|
192
|
+
|
|
193
|
+
let item: T = await this._repository.findById(id)
|
|
194
|
+
|
|
140
195
|
if (item && this.transformRead) {
|
|
141
196
|
item = await this.transformRead(item)
|
|
142
197
|
}
|
|
198
|
+
|
|
199
|
+
item = await this.validateOutput(item)
|
|
200
|
+
|
|
143
201
|
return item
|
|
202
|
+
|
|
144
203
|
} catch (e) {
|
|
145
204
|
console.error("Error findById", {
|
|
146
205
|
name: e?.name,
|
|
@@ -151,32 +210,47 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
151
210
|
}
|
|
152
211
|
}
|
|
153
212
|
|
|
154
|
-
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
async findOneBy(field: string, value: any): Promise<T | null> {
|
|
155
216
|
try {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
217
|
+
|
|
218
|
+
let item: T = await this._repository.findOneBy(field, value)
|
|
219
|
+
|
|
220
|
+
if (item && this.transformRead) {
|
|
221
|
+
item = await this.transformRead(item)
|
|
159
222
|
}
|
|
160
|
-
|
|
223
|
+
|
|
224
|
+
item = await this.validateOutput(item)
|
|
225
|
+
|
|
226
|
+
return item
|
|
161
227
|
} catch (e) {
|
|
162
|
-
console.error("Error
|
|
228
|
+
console.error("Error findOneBy", {
|
|
163
229
|
name: e?.name,
|
|
164
230
|
message: e?.message,
|
|
165
231
|
stack: e?.stack,
|
|
166
232
|
});
|
|
167
233
|
throw e;
|
|
168
234
|
}
|
|
235
|
+
|
|
169
236
|
}
|
|
170
237
|
|
|
171
|
-
async
|
|
238
|
+
async findOne({
|
|
239
|
+
search = '',
|
|
240
|
+
filters = []
|
|
241
|
+
}: IDraxFindOneOptions): Promise<T> {
|
|
172
242
|
try {
|
|
173
|
-
let item
|
|
243
|
+
let item = await this._repository.findOne({search, filters});
|
|
244
|
+
|
|
174
245
|
if (item && this.transformRead) {
|
|
175
246
|
item = await this.transformRead(item)
|
|
176
247
|
}
|
|
248
|
+
|
|
249
|
+
item = await this.validateOutput(item)
|
|
250
|
+
|
|
177
251
|
return item
|
|
178
252
|
} catch (e) {
|
|
179
|
-
console.error("Error
|
|
253
|
+
console.error("Error findOne", {
|
|
180
254
|
name: e?.name,
|
|
181
255
|
message: e?.message,
|
|
182
256
|
stack: e?.stack,
|
|
@@ -186,6 +260,30 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
186
260
|
|
|
187
261
|
}
|
|
188
262
|
|
|
263
|
+
async findByIds(ids: Array<string>): Promise<T[]> {
|
|
264
|
+
try {
|
|
265
|
+
|
|
266
|
+
let items: T[] = await this._repository.findByIds(ids)
|
|
267
|
+
|
|
268
|
+
if (this.transformRead) {
|
|
269
|
+
items = await Promise.all(items.map(item => this.transformRead(item)))
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if(this._fullSchema){
|
|
273
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)))
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return items
|
|
277
|
+
} catch (e) {
|
|
278
|
+
console.error("Error findByIds", {
|
|
279
|
+
name: e?.name,
|
|
280
|
+
message: e?.message,
|
|
281
|
+
stack: e?.stack,
|
|
282
|
+
});
|
|
283
|
+
throw e;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
189
287
|
async findBy(field: string, value: any, limit: number = 1000): Promise<T[] | null> {
|
|
190
288
|
try {
|
|
191
289
|
|
|
@@ -193,6 +291,9 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
193
291
|
if (this.transformRead) {
|
|
194
292
|
items = await Promise.all(items.map(item => this.transformRead(item)))
|
|
195
293
|
}
|
|
294
|
+
if(this._fullSchema){
|
|
295
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)))
|
|
296
|
+
}
|
|
196
297
|
return items
|
|
197
298
|
} catch (e) {
|
|
198
299
|
console.error("Error findBy", {
|
|
@@ -211,6 +312,9 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
211
312
|
if (this.transformRead) {
|
|
212
313
|
items = await Promise.all(items.map(item => this.transformRead(item)))
|
|
213
314
|
}
|
|
315
|
+
if(this._fullSchema){
|
|
316
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)))
|
|
317
|
+
}
|
|
214
318
|
return items
|
|
215
319
|
} catch (e) {
|
|
216
320
|
console.error("Error fetchAll", {
|
|
@@ -230,6 +334,9 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
230
334
|
if (this.transformRead) {
|
|
231
335
|
items = await Promise.all(items.map(item => this.transformRead(item)))
|
|
232
336
|
}
|
|
337
|
+
if(this._fullSchema){
|
|
338
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)))
|
|
339
|
+
}
|
|
233
340
|
return items
|
|
234
341
|
} catch (e) {
|
|
235
342
|
console.error("Error search", {
|
|
@@ -259,6 +366,10 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
259
366
|
pagination.items = await Promise.all(pagination.items.map(item => this.transformRead(item)))
|
|
260
367
|
}
|
|
261
368
|
|
|
369
|
+
if(this._fullSchema){
|
|
370
|
+
pagination.items = await Promise.all(pagination.items.map(item => this.validateOutput(item)))
|
|
371
|
+
}
|
|
372
|
+
|
|
262
373
|
return pagination;
|
|
263
374
|
} catch (e) {
|
|
264
375
|
console.error("Error paginate", {
|
|
@@ -284,6 +395,9 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
284
395
|
if (this.transformRead) {
|
|
285
396
|
items = await Promise.all(items.map(item => this.transformRead(item)))
|
|
286
397
|
}
|
|
398
|
+
if(this._fullSchema){
|
|
399
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)))
|
|
400
|
+
}
|
|
287
401
|
return items;
|
|
288
402
|
} catch (e) {
|
|
289
403
|
console.error("Error find", {
|
|
@@ -296,25 +410,9 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
296
410
|
|
|
297
411
|
}
|
|
298
412
|
|
|
299
|
-
async findOne({
|
|
300
|
-
search = '',
|
|
301
|
-
filters = []
|
|
302
|
-
}: IDraxFindOneOptions): Promise<T> {
|
|
303
|
-
try {
|
|
304
|
-
let item = await this._repository.findOne({search, filters});
|
|
305
|
-
return item;
|
|
306
|
-
} catch (e) {
|
|
307
|
-
console.error("Error findOne", {
|
|
308
|
-
name: e?.name,
|
|
309
|
-
message: e?.message,
|
|
310
|
-
stack: e?.stack,
|
|
311
|
-
});
|
|
312
|
-
throw e;
|
|
313
|
-
}
|
|
314
413
|
|
|
315
|
-
}
|
|
316
414
|
|
|
317
|
-
async groupBy({fields= [], filters= [], dateFormat= 'day'}: IDraxGroupByOptions): Promise<Array<any>> {
|
|
415
|
+
async groupBy({fields = [], filters = [], dateFormat = 'day'}: IDraxGroupByOptions): Promise<Array<any>> {
|
|
318
416
|
return await this._repository.groupBy({fields, filters, dateFormat})
|
|
319
417
|
}
|
|
320
418
|
|
|
@@ -346,7 +444,14 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
|
|
|
346
444
|
exporter = new ExportJson({cursor, destinationPath: destinationPath, headers, fileName});
|
|
347
445
|
return await exporter.process()
|
|
348
446
|
case 'CSV':
|
|
349
|
-
exporter = new ExportCsv({
|
|
447
|
+
exporter = new ExportCsv({
|
|
448
|
+
cursor,
|
|
449
|
+
destinationPath: destinationPath,
|
|
450
|
+
headers,
|
|
451
|
+
headersTranslate,
|
|
452
|
+
fileName,
|
|
453
|
+
separator
|
|
454
|
+
});
|
|
350
455
|
return await exporter.process()
|
|
351
456
|
default:
|
|
352
457
|
throw new Error(`Unsupported export format: ${format}`);
|