@drax/crud-back 1.1.1 → 1.3.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.
- package/dist/controllers/AbstractFastifyController.js +12 -4
- package/dist/repository/AbstractMongoRepository.js +1 -1
- package/dist/services/AbstractService.js +150 -86
- package/package.json +3 -3
- package/src/controllers/AbstractFastifyController.ts +14 -4
- package/src/repository/AbstractMongoRepository.ts +1 -1
- package/src/services/AbstractService.ts +199 -94
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
- package/types/services/AbstractService.d.ts +10 -4
- package/types/services/AbstractService.d.ts.map +1 -1
|
@@ -220,8 +220,12 @@ class AbstractFastifyController extends CommonController {
|
|
|
220
220
|
this.assertUser(preItem, request.rbac);
|
|
221
221
|
}
|
|
222
222
|
//Definido el tenant/user en el create no debe modificarse en un update
|
|
223
|
-
|
|
224
|
-
|
|
223
|
+
if (this.tenantSetter) {
|
|
224
|
+
delete payload[this.tenantField];
|
|
225
|
+
}
|
|
226
|
+
if (this.userSetter) {
|
|
227
|
+
delete payload[this.userField];
|
|
228
|
+
}
|
|
225
229
|
await this.preUpdate(request, payload);
|
|
226
230
|
let item = await this.service.update(id, payload);
|
|
227
231
|
if (!item) {
|
|
@@ -259,8 +263,12 @@ class AbstractFastifyController extends CommonController {
|
|
|
259
263
|
this.assertUser(preItem, request.rbac);
|
|
260
264
|
}
|
|
261
265
|
//Definido el tenant/user en el create no debe modificarse en un update
|
|
262
|
-
|
|
263
|
-
|
|
266
|
+
if (this.tenantSetter) {
|
|
267
|
+
delete payload[this.tenantField];
|
|
268
|
+
}
|
|
269
|
+
if (this.userSetter) {
|
|
270
|
+
delete payload[this.userField];
|
|
271
|
+
}
|
|
264
272
|
await this.preUpdatePartial(request, payload);
|
|
265
273
|
let item = await this.service.updatePartial(id, payload);
|
|
266
274
|
if (!item) {
|
|
@@ -356,7 +356,7 @@ class AbstractMongoRepository {
|
|
|
356
356
|
pipeline.push({
|
|
357
357
|
$project: finalProjectFields
|
|
358
358
|
}, { $sort: { count: -1 } });
|
|
359
|
-
console.log("pipeline", JSON.stringify(pipeline, null, 2))
|
|
359
|
+
// console.log("pipeline", JSON.stringify(pipeline, null, 2))
|
|
360
360
|
const result = await this._model.aggregate(pipeline).exec();
|
|
361
361
|
return result;
|
|
362
362
|
}
|
|
@@ -3,84 +3,117 @@ import { ZodError } from "zod";
|
|
|
3
3
|
import ExportCsv from "../exports/ExportCsv.js";
|
|
4
4
|
import ExportJson from "../exports/ExportJson.js";
|
|
5
5
|
class AbstractService {
|
|
6
|
-
constructor(repository,
|
|
6
|
+
constructor(repository, baseSchema, fullSchema) {
|
|
7
|
+
this._validateOutput = true;
|
|
7
8
|
this._repository = repository;
|
|
8
|
-
this.
|
|
9
|
+
this._baseSchema = baseSchema;
|
|
10
|
+
this._fullSchema = fullSchema;
|
|
9
11
|
}
|
|
10
|
-
async
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
async validateInputCreate(data) {
|
|
13
|
+
if (this._baseSchema) {
|
|
14
|
+
try {
|
|
15
|
+
return await this._baseSchema.parseAsync(data);
|
|
14
16
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
catch (e) {
|
|
18
|
+
console.error("Error on validateInputCreate", {
|
|
19
|
+
name: e?.name,
|
|
20
|
+
message: e?.message,
|
|
21
|
+
stack: e?.stack,
|
|
22
|
+
});
|
|
23
|
+
if (e instanceof ZodError) {
|
|
24
|
+
throw ZodErrorToValidationError(e, data);
|
|
25
|
+
}
|
|
26
|
+
throw e;
|
|
17
27
|
}
|
|
18
|
-
const item = await this._repository.create(data);
|
|
19
|
-
if (this.onCreated) {
|
|
20
|
-
await this.onCreated(item);
|
|
21
|
-
}
|
|
22
|
-
return item;
|
|
23
|
-
}
|
|
24
|
-
catch (e) {
|
|
25
|
-
console.error("Error create", {
|
|
26
|
-
name: e?.name,
|
|
27
|
-
message: e?.message,
|
|
28
|
-
stack: e?.stack,
|
|
29
|
-
});
|
|
30
|
-
if (e instanceof ZodError) {
|
|
31
|
-
throw ZodErrorToValidationError(e, data);
|
|
32
|
-
}
|
|
33
|
-
throw e;
|
|
34
28
|
}
|
|
29
|
+
return data;
|
|
35
30
|
}
|
|
36
|
-
async
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
if (this.transformUpdate) {
|
|
42
|
-
data = await this.transformUpdate(data);
|
|
31
|
+
async validateInputUpdate(data) {
|
|
32
|
+
if (this._baseSchema) {
|
|
33
|
+
try {
|
|
34
|
+
return await this._baseSchema.partial().parseAsync(data);
|
|
43
35
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.error("Error on validateInputUpdate", {
|
|
38
|
+
name: e?.name,
|
|
39
|
+
message: e?.message,
|
|
40
|
+
stack: e?.stack,
|
|
41
|
+
});
|
|
42
|
+
if (e instanceof ZodError) {
|
|
43
|
+
throw ZodErrorToValidationError(e, data);
|
|
44
|
+
}
|
|
45
|
+
throw e;
|
|
47
46
|
}
|
|
48
|
-
return item;
|
|
49
47
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
async validateInputUpdatePartial(data) {
|
|
51
|
+
if (this._baseSchema) {
|
|
52
|
+
try {
|
|
53
|
+
return await this._baseSchema.partial().parseAsync(data);
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.error("Error on validateInputUpdatePartial", {
|
|
57
|
+
name: e?.name,
|
|
58
|
+
message: e?.message,
|
|
59
|
+
stack: e?.stack,
|
|
60
|
+
});
|
|
61
|
+
if (e instanceof ZodError) {
|
|
62
|
+
throw ZodErrorToValidationError(e, data);
|
|
63
|
+
}
|
|
64
|
+
throw e;
|
|
58
65
|
}
|
|
59
|
-
throw e;
|
|
60
66
|
}
|
|
67
|
+
return data;
|
|
61
68
|
}
|
|
62
|
-
async
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
async validateOutput(item) {
|
|
70
|
+
if (this._validateOutput && item && this._fullSchema) {
|
|
71
|
+
try {
|
|
72
|
+
return await this._fullSchema.parseAsync(item);
|
|
66
73
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.error("Error on validateOutput", {
|
|
76
|
+
name: e?.name,
|
|
77
|
+
message: e?.message,
|
|
78
|
+
stack: e?.stack,
|
|
79
|
+
});
|
|
80
|
+
throw e;
|
|
70
81
|
}
|
|
71
|
-
return item;
|
|
72
82
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
return item;
|
|
84
|
+
}
|
|
85
|
+
async create(data) {
|
|
86
|
+
data = await this.validateInputCreate(data);
|
|
87
|
+
if (this.transformCreate) {
|
|
88
|
+
data = await this.transformCreate(data);
|
|
89
|
+
}
|
|
90
|
+
let item = await this._repository.create(data);
|
|
91
|
+
if (this.onCreated) {
|
|
92
|
+
await this.onCreated(item);
|
|
83
93
|
}
|
|
94
|
+
item = await this.validateOutput(item);
|
|
95
|
+
return item;
|
|
96
|
+
}
|
|
97
|
+
async update(id, data) {
|
|
98
|
+
data = await this.validateInputUpdate(data);
|
|
99
|
+
if (this.transformUpdate) {
|
|
100
|
+
data = await this.transformUpdate(data);
|
|
101
|
+
}
|
|
102
|
+
let item = await this._repository.update(id, data);
|
|
103
|
+
if (this.onUpdated) {
|
|
104
|
+
await this.onUpdated(item);
|
|
105
|
+
}
|
|
106
|
+
item = await this.validateOutput(item);
|
|
107
|
+
return item;
|
|
108
|
+
}
|
|
109
|
+
async updatePartial(id, data) {
|
|
110
|
+
data = await this.validateInputUpdatePartial(data);
|
|
111
|
+
let item = await this._repository.updatePartial(id, data);
|
|
112
|
+
if (this.onUpdated) {
|
|
113
|
+
await this.onUpdated(item);
|
|
114
|
+
}
|
|
115
|
+
item = await this.validateOutput(item);
|
|
116
|
+
return item;
|
|
84
117
|
}
|
|
85
118
|
async delete(id) {
|
|
86
119
|
try {
|
|
@@ -108,6 +141,7 @@ class AbstractService {
|
|
|
108
141
|
if (item && this.transformRead) {
|
|
109
142
|
item = await this.transformRead(item);
|
|
110
143
|
}
|
|
144
|
+
item = await this.validateOutput(item);
|
|
111
145
|
return item;
|
|
112
146
|
}
|
|
113
147
|
catch (e) {
|
|
@@ -119,16 +153,17 @@ class AbstractService {
|
|
|
119
153
|
throw e;
|
|
120
154
|
}
|
|
121
155
|
}
|
|
122
|
-
async
|
|
156
|
+
async findOneBy(field, value) {
|
|
123
157
|
try {
|
|
124
|
-
let
|
|
125
|
-
if (this.transformRead) {
|
|
126
|
-
|
|
158
|
+
let item = await this._repository.findOneBy(field, value);
|
|
159
|
+
if (item && this.transformRead) {
|
|
160
|
+
item = await this.transformRead(item);
|
|
127
161
|
}
|
|
128
|
-
|
|
162
|
+
item = await this.validateOutput(item);
|
|
163
|
+
return item;
|
|
129
164
|
}
|
|
130
165
|
catch (e) {
|
|
131
|
-
console.error("Error
|
|
166
|
+
console.error("Error findOneBy", {
|
|
132
167
|
name: e?.name,
|
|
133
168
|
message: e?.message,
|
|
134
169
|
stack: e?.stack,
|
|
@@ -136,16 +171,37 @@ class AbstractService {
|
|
|
136
171
|
throw e;
|
|
137
172
|
}
|
|
138
173
|
}
|
|
139
|
-
async
|
|
174
|
+
async findOne({ search = '', filters = [] }) {
|
|
140
175
|
try {
|
|
141
|
-
let item = await this._repository.
|
|
176
|
+
let item = await this._repository.findOne({ search, filters });
|
|
142
177
|
if (item && this.transformRead) {
|
|
143
178
|
item = await this.transformRead(item);
|
|
144
179
|
}
|
|
180
|
+
item = await this.validateOutput(item);
|
|
145
181
|
return item;
|
|
146
182
|
}
|
|
147
183
|
catch (e) {
|
|
148
|
-
console.error("Error
|
|
184
|
+
console.error("Error findOne", {
|
|
185
|
+
name: e?.name,
|
|
186
|
+
message: e?.message,
|
|
187
|
+
stack: e?.stack,
|
|
188
|
+
});
|
|
189
|
+
throw e;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async findByIds(ids) {
|
|
193
|
+
try {
|
|
194
|
+
let items = await this._repository.findByIds(ids);
|
|
195
|
+
if (this.transformRead) {
|
|
196
|
+
items = await Promise.all(items.map(item => this.transformRead(item)));
|
|
197
|
+
}
|
|
198
|
+
if (this._fullSchema) {
|
|
199
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)));
|
|
200
|
+
}
|
|
201
|
+
return items;
|
|
202
|
+
}
|
|
203
|
+
catch (e) {
|
|
204
|
+
console.error("Error findByIds", {
|
|
149
205
|
name: e?.name,
|
|
150
206
|
message: e?.message,
|
|
151
207
|
stack: e?.stack,
|
|
@@ -159,6 +215,9 @@ class AbstractService {
|
|
|
159
215
|
if (this.transformRead) {
|
|
160
216
|
items = await Promise.all(items.map(item => this.transformRead(item)));
|
|
161
217
|
}
|
|
218
|
+
if (this._fullSchema) {
|
|
219
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)));
|
|
220
|
+
}
|
|
162
221
|
return items;
|
|
163
222
|
}
|
|
164
223
|
catch (e) {
|
|
@@ -176,6 +235,9 @@ class AbstractService {
|
|
|
176
235
|
if (this.transformRead) {
|
|
177
236
|
items = await Promise.all(items.map(item => this.transformRead(item)));
|
|
178
237
|
}
|
|
238
|
+
if (this._fullSchema) {
|
|
239
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)));
|
|
240
|
+
}
|
|
179
241
|
return items;
|
|
180
242
|
}
|
|
181
243
|
catch (e) {
|
|
@@ -193,6 +255,9 @@ class AbstractService {
|
|
|
193
255
|
if (this.transformRead) {
|
|
194
256
|
items = await Promise.all(items.map(item => this.transformRead(item)));
|
|
195
257
|
}
|
|
258
|
+
if (this._fullSchema) {
|
|
259
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)));
|
|
260
|
+
}
|
|
196
261
|
return items;
|
|
197
262
|
}
|
|
198
263
|
catch (e) {
|
|
@@ -210,6 +275,9 @@ class AbstractService {
|
|
|
210
275
|
if (this.transformRead) {
|
|
211
276
|
pagination.items = await Promise.all(pagination.items.map(item => this.transformRead(item)));
|
|
212
277
|
}
|
|
278
|
+
if (this._fullSchema) {
|
|
279
|
+
pagination.items = await Promise.all(pagination.items.map(item => this.validateOutput(item)));
|
|
280
|
+
}
|
|
213
281
|
return pagination;
|
|
214
282
|
}
|
|
215
283
|
catch (e) {
|
|
@@ -227,6 +295,9 @@ class AbstractService {
|
|
|
227
295
|
if (this.transformRead) {
|
|
228
296
|
items = await Promise.all(items.map(item => this.transformRead(item)));
|
|
229
297
|
}
|
|
298
|
+
if (this._fullSchema) {
|
|
299
|
+
items = await Promise.all(items.map(item => this.validateOutput(item)));
|
|
300
|
+
}
|
|
230
301
|
return items;
|
|
231
302
|
}
|
|
232
303
|
catch (e) {
|
|
@@ -238,20 +309,6 @@ class AbstractService {
|
|
|
238
309
|
throw e;
|
|
239
310
|
}
|
|
240
311
|
}
|
|
241
|
-
async findOne({ search = '', filters = [] }) {
|
|
242
|
-
try {
|
|
243
|
-
let item = await this._repository.findOne({ search, filters });
|
|
244
|
-
return item;
|
|
245
|
-
}
|
|
246
|
-
catch (e) {
|
|
247
|
-
console.error("Error findOne", {
|
|
248
|
-
name: e?.name,
|
|
249
|
-
message: e?.message,
|
|
250
|
-
stack: e?.stack,
|
|
251
|
-
});
|
|
252
|
-
throw e;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
312
|
async groupBy({ fields = [], filters = [], dateFormat = 'day' }) {
|
|
256
313
|
return await this._repository.groupBy({ fields, filters, dateFormat });
|
|
257
314
|
}
|
|
@@ -270,7 +327,14 @@ class AbstractService {
|
|
|
270
327
|
exporter = new ExportJson({ cursor, destinationPath: destinationPath, headers, fileName });
|
|
271
328
|
return await exporter.process();
|
|
272
329
|
case 'CSV':
|
|
273
|
-
exporter = new ExportCsv({
|
|
330
|
+
exporter = new ExportCsv({
|
|
331
|
+
cursor,
|
|
332
|
+
destinationPath: destinationPath,
|
|
333
|
+
headers,
|
|
334
|
+
headersTranslate,
|
|
335
|
+
fileName,
|
|
336
|
+
separator
|
|
337
|
+
});
|
|
274
338
|
return await exporter.process();
|
|
275
339
|
default:
|
|
276
340
|
throw new Error(`Unsupported export format: ${format}`);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.3.1",
|
|
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": "^1.1.1",
|
|
26
26
|
"@drax/common-share": "^1.0.0",
|
|
27
27
|
"@drax/identity-share": "^1.0.0",
|
|
28
|
-
"@drax/media-back": "^1.
|
|
28
|
+
"@drax/media-back": "^1.3.1",
|
|
29
29
|
"@graphql-tools/load-files": "^7.0.0",
|
|
30
30
|
"@graphql-tools/merge": "^9.0.4",
|
|
31
31
|
"mongoose": "^8.21.0",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"tsc-alias": "^1.8.10",
|
|
47
47
|
"typescript": "^5.6.2"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "c6b9faf2c5fc4a2d339509997544fd0aadb47832"
|
|
50
50
|
}
|
|
@@ -320,8 +320,13 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
//Definido el tenant/user en el create no debe modificarse en un update
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
if(this.tenantSetter) {
|
|
324
|
+
delete payload[this.tenantField]
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if(this.userSetter){
|
|
328
|
+
delete payload[this.userField]
|
|
329
|
+
}
|
|
325
330
|
|
|
326
331
|
await this.preUpdate(request, payload)
|
|
327
332
|
let item = await this.service.update(id, payload as U)
|
|
@@ -371,8 +376,13 @@ class AbstractFastifyController<T, C, U> extends CommonController {
|
|
|
371
376
|
}
|
|
372
377
|
|
|
373
378
|
//Definido el tenant/user en el create no debe modificarse en un update
|
|
374
|
-
|
|
375
|
-
|
|
379
|
+
if(this.tenantSetter) {
|
|
380
|
+
delete payload[this.tenantField]
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if(this.userSetter){
|
|
384
|
+
delete payload[this.userField]
|
|
385
|
+
}
|
|
376
386
|
|
|
377
387
|
await this.preUpdatePartial(request, payload)
|
|
378
388
|
let item = await this.service.updatePartial(id, payload as U)
|
|
@@ -471,7 +471,7 @@ class AbstractMongoRepository<T, C, U> implements IDraxCrud<T, C, U> {
|
|
|
471
471
|
},
|
|
472
472
|
{$sort: {count: -1}}
|
|
473
473
|
)
|
|
474
|
-
console.log("pipeline", JSON.stringify(pipeline, null, 2))
|
|
474
|
+
// console.log("pipeline", JSON.stringify(pipeline, null, 2))
|
|
475
475
|
const result = await this._model.aggregate(pipeline).exec()
|
|
476
476
|
return result
|
|
477
477
|
}
|