@flusys/nestjs-shared 4.0.2 → 4.1.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/README.md +448 -1561
- package/cjs/classes/api-controller.class.js +207 -11
- package/cjs/classes/api-service.class.js +40 -4
- package/cjs/dtos/get-by-ids.dto.js +65 -0
- package/cjs/dtos/index.js +1 -0
- package/cjs/entities/index.js +1 -0
- package/cjs/entities/raw-type.js +4 -0
- package/classes/api-controller.class.d.ts +9 -3
- package/classes/api-service.class.d.ts +6 -5
- package/dtos/get-by-ids.dto.d.ts +4 -0
- package/dtos/index.d.ts +1 -0
- package/entities/index.d.ts +1 -0
- package/entities/raw-type.d.ts +1 -0
- package/fesm/classes/api-controller.class.js +208 -12
- package/fesm/classes/api-service.class.js +40 -4
- package/fesm/dtos/get-by-ids.dto.js +55 -0
- package/fesm/dtos/index.js +1 -0
- package/fesm/entities/index.js +1 -0
- package/fesm/entities/raw-type.js +1 -0
- package/interfaces/api.interface.d.ts +2 -0
- package/package.json +2 -2
|
@@ -8,14 +8,15 @@ Object.defineProperty(exports, "createApiController", {
|
|
|
8
8
|
return createApiController;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _decorators = require("../decorators");
|
|
12
|
-
const _dtos = require("../dtos");
|
|
13
|
-
const _guards = require("../guards");
|
|
14
|
-
const _interceptors = require("../interceptors");
|
|
15
11
|
const _common = require("@nestjs/common");
|
|
16
12
|
const _swagger = require("@nestjs/swagger");
|
|
17
13
|
const _classtransformer = require("class-transformer");
|
|
14
|
+
const _decorators = require("../decorators");
|
|
18
15
|
const _apiresponsedecorator = require("../decorators/api-response.decorator");
|
|
16
|
+
const _dtos = require("../dtos");
|
|
17
|
+
const _exceptions = require("../exceptions");
|
|
18
|
+
const _guards = require("../guards");
|
|
19
|
+
const _interceptors = require("../interceptors");
|
|
19
20
|
function _define_property(obj, key, value) {
|
|
20
21
|
if (key in obj) {
|
|
21
22
|
Object.defineProperty(obj, key, {
|
|
@@ -54,6 +55,24 @@ function _ts_param(paramIndex, decorator) {
|
|
|
54
55
|
};
|
|
55
56
|
return config;
|
|
56
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Helper to check if endpoint is enabled
|
|
60
|
+
*/ function isEndpointEnabled(endpoint, enabledEndpoints) {
|
|
61
|
+
if (!enabledEndpoints || enabledEndpoints === 'all') return true;
|
|
62
|
+
return enabledEndpoints.includes(endpoint);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Helper to conditionally exclude endpoint from Swagger if disabled
|
|
66
|
+
*/ function createEndpointDecorators(security, endpoint, enabledEndpoints) {
|
|
67
|
+
const decorators = [];
|
|
68
|
+
// Add security decorators
|
|
69
|
+
decorators.push(createSecurityDecorators(security));
|
|
70
|
+
// Exclude from Swagger if endpoint is disabled
|
|
71
|
+
if (!isEndpointEnabled(endpoint, enabledEndpoints)) {
|
|
72
|
+
decorators.push((0, _swagger.ApiExcludeEndpoint)());
|
|
73
|
+
}
|
|
74
|
+
return (0, _common.applyDecorators)(...decorators);
|
|
75
|
+
}
|
|
57
76
|
/**
|
|
58
77
|
* Creates security decorators based on configuration
|
|
59
78
|
*/ function createSecurityDecorators(security) {
|
|
@@ -96,7 +115,10 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
96
115
|
'insert',
|
|
97
116
|
'insertMany',
|
|
98
117
|
'getById',
|
|
118
|
+
'getByIds',
|
|
99
119
|
'getAll',
|
|
120
|
+
'bulkUpsert',
|
|
121
|
+
'getByFilter',
|
|
100
122
|
'update',
|
|
101
123
|
'updateMany',
|
|
102
124
|
'delete'
|
|
@@ -115,13 +137,23 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
115
137
|
insert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insert),
|
|
116
138
|
insertMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insertMany),
|
|
117
139
|
getById: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getById),
|
|
140
|
+
getByIds: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByIds),
|
|
118
141
|
getAll: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getAll),
|
|
142
|
+
getByFilter: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByFilter),
|
|
143
|
+
bulkUpsert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.bulkUpsert),
|
|
119
144
|
update: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.update),
|
|
120
145
|
updateMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.updateMany),
|
|
121
146
|
delete: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.delete)
|
|
122
147
|
};
|
|
123
148
|
let ApiController = class ApiController {
|
|
149
|
+
isEnabled(endpoint) {
|
|
150
|
+
if (this.enabledEndpoints === 'all') return true;
|
|
151
|
+
return Array.isArray(this.enabledEndpoints) && this.enabledEndpoints.includes(endpoint);
|
|
152
|
+
}
|
|
124
153
|
async insert(addDto, user) {
|
|
154
|
+
if (!this.isEnabled('insert')) {
|
|
155
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'insert' is disabled`);
|
|
156
|
+
}
|
|
125
157
|
const entity = await this.service.insert(addDto, user);
|
|
126
158
|
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
|
|
127
159
|
return {
|
|
@@ -132,6 +164,9 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
132
164
|
};
|
|
133
165
|
}
|
|
134
166
|
async insertMany(addDto, user) {
|
|
167
|
+
if (!this.isEnabled('insertMany')) {
|
|
168
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'insertMany' is disabled`);
|
|
169
|
+
}
|
|
135
170
|
const entities = await this.service.insertMany(addDto, user);
|
|
136
171
|
const data = entities.map((item)=>(0, _classtransformer.plainToInstance)(responseDtoClass, item));
|
|
137
172
|
return {
|
|
@@ -150,6 +185,9 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
150
185
|
};
|
|
151
186
|
}
|
|
152
187
|
async getById(id, body, user) {
|
|
188
|
+
if (!this.isEnabled('getById')) {
|
|
189
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'getById' is disabled`);
|
|
190
|
+
}
|
|
153
191
|
const entity = await this.service.findById(id, user, body?.select);
|
|
154
192
|
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
|
|
155
193
|
return {
|
|
@@ -159,7 +197,30 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
159
197
|
data
|
|
160
198
|
};
|
|
161
199
|
}
|
|
200
|
+
async getByIds(body, user) {
|
|
201
|
+
if (!this.isEnabled('getByIds')) {
|
|
202
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'getByIds' is disabled`);
|
|
203
|
+
}
|
|
204
|
+
const entities = await this.service.findByIds(body.ids, user, body?.select);
|
|
205
|
+
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entities);
|
|
206
|
+
return {
|
|
207
|
+
success: true,
|
|
208
|
+
message: `${data.length} ${entityName}${data.length !== 1 ? 's' : ''} retrieved successfully`,
|
|
209
|
+
messageKey: `${entityName}.get.by.ids.success`,
|
|
210
|
+
data,
|
|
211
|
+
meta: {
|
|
212
|
+
total: data.length,
|
|
213
|
+
page: 0,
|
|
214
|
+
pageSize: data.length,
|
|
215
|
+
count: data.length,
|
|
216
|
+
totalPages: 1
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
162
220
|
async update(updateDto, user) {
|
|
221
|
+
if (!this.isEnabled('update')) {
|
|
222
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'update' is disabled`);
|
|
223
|
+
}
|
|
163
224
|
const entity = await this.service.update(updateDto, user);
|
|
164
225
|
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
|
|
165
226
|
return {
|
|
@@ -170,6 +231,9 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
170
231
|
};
|
|
171
232
|
}
|
|
172
233
|
async updateMany(updateDtos, user) {
|
|
234
|
+
if (!this.isEnabled('updateMany')) {
|
|
235
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'updateMany' is disabled`);
|
|
236
|
+
}
|
|
173
237
|
const entities = await this.service.updateMany(updateDtos, user);
|
|
174
238
|
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entities);
|
|
175
239
|
return {
|
|
@@ -187,7 +251,63 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
187
251
|
}
|
|
188
252
|
};
|
|
189
253
|
}
|
|
254
|
+
async bulkUpsert(dtos, user) {
|
|
255
|
+
if (!this.isEnabled('bulkUpsert')) {
|
|
256
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'bulkUpsert' is disabled`);
|
|
257
|
+
}
|
|
258
|
+
const toInsert = [];
|
|
259
|
+
const toUpdate = [];
|
|
260
|
+
for (const dto of dtos){
|
|
261
|
+
if ('id' in dto && dto.id) {
|
|
262
|
+
toUpdate.push(dto);
|
|
263
|
+
} else {
|
|
264
|
+
toInsert.push(dto);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const allEntities = await this.service.bulkUpsert(toInsert, toUpdate, user);
|
|
268
|
+
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, allEntities);
|
|
269
|
+
return {
|
|
270
|
+
success: true,
|
|
271
|
+
message: `${data.length} ${entityName}s upserted successfully`,
|
|
272
|
+
messageKey: `${entityName}.upsert.many.success`,
|
|
273
|
+
messageVariables: {
|
|
274
|
+
count: data.length
|
|
275
|
+
},
|
|
276
|
+
data,
|
|
277
|
+
meta: {
|
|
278
|
+
count: data.length,
|
|
279
|
+
total: dtos.length,
|
|
280
|
+
failed: dtos.length - data.length
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
async getByFilter(filter, user) {
|
|
285
|
+
if (!this.isEnabled('getByFilter')) {
|
|
286
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'getByFilter' is disabled`);
|
|
287
|
+
}
|
|
288
|
+
const result = await this.service.getAll('', {
|
|
289
|
+
filter,
|
|
290
|
+
pagination: {
|
|
291
|
+
currentPage: 0,
|
|
292
|
+
pageSize: 1
|
|
293
|
+
}
|
|
294
|
+
}, user);
|
|
295
|
+
if (!result.data || result.data.length === 0) {
|
|
296
|
+
throw new _exceptions.NotFoundException(entityName);
|
|
297
|
+
}
|
|
298
|
+
const entity = result.data[0];
|
|
299
|
+
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
|
|
300
|
+
return {
|
|
301
|
+
success: true,
|
|
302
|
+
message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} retrieved successfully`,
|
|
303
|
+
messageKey: `${entityName}.get.by.filter.success`,
|
|
304
|
+
data
|
|
305
|
+
};
|
|
306
|
+
}
|
|
190
307
|
async getAll(filterAndPaginationDto, user, search) {
|
|
308
|
+
if (!this.isEnabled('getAll')) {
|
|
309
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'getAll' is disabled`);
|
|
310
|
+
}
|
|
191
311
|
const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
|
|
192
312
|
const data = (0, _classtransformer.plainToInstance)(responseDtoClass, result.data);
|
|
193
313
|
const page = filterAndPaginationDto.pagination?.currentPage ?? 0;
|
|
@@ -209,6 +329,9 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
209
329
|
};
|
|
210
330
|
}
|
|
211
331
|
async delete(deleteDto, user) {
|
|
332
|
+
if (!this.isEnabled('delete')) {
|
|
333
|
+
throw new _exceptions.ForbiddenException(`Endpoint 'delete' is disabled`);
|
|
334
|
+
}
|
|
212
335
|
await this.service.delete(deleteDto, user);
|
|
213
336
|
const count = Array.isArray(deleteDto.id) ? deleteDto.id.length : 1;
|
|
214
337
|
const action = deleteDto.type === 'restore' ? 'restore' : 'delete';
|
|
@@ -223,11 +346,13 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
223
346
|
}
|
|
224
347
|
constructor(service){
|
|
225
348
|
_define_property(this, "service", void 0);
|
|
349
|
+
_define_property(this, "enabledEndpoints", void 0);
|
|
226
350
|
this.service = service;
|
|
351
|
+
this.enabledEndpoints = options.enabledEndpoints ?? 'all';
|
|
227
352
|
}
|
|
228
353
|
};
|
|
229
354
|
_ts_decorate([
|
|
230
|
-
|
|
355
|
+
createEndpointDecorators(security.insert, 'insert', options.enabledEndpoints),
|
|
231
356
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
232
357
|
(0, _common.Post)('insert'),
|
|
233
358
|
(0, _common.HttpCode)(_common.HttpStatus.CREATED),
|
|
@@ -255,7 +380,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
255
380
|
_ts_metadata("design:returntype", Promise)
|
|
256
381
|
], ApiController.prototype, "insert", null);
|
|
257
382
|
_ts_decorate([
|
|
258
|
-
|
|
383
|
+
createEndpointDecorators(security.insertMany, 'insertMany', options.enabledEndpoints),
|
|
259
384
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
260
385
|
(0, _common.Post)('insert-many'),
|
|
261
386
|
(0, _common.HttpCode)(_common.HttpStatus.CREATED),
|
|
@@ -284,7 +409,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
284
409
|
_ts_metadata("design:returntype", Promise)
|
|
285
410
|
], ApiController.prototype, "insertMany", null);
|
|
286
411
|
_ts_decorate([
|
|
287
|
-
|
|
412
|
+
createEndpointDecorators(security.getById, 'getById', options.enabledEndpoints),
|
|
288
413
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
289
414
|
(0, _common.Post)('get/:id'),
|
|
290
415
|
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
@@ -314,7 +439,29 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
314
439
|
_ts_metadata("design:returntype", Promise)
|
|
315
440
|
], ApiController.prototype, "getById", null);
|
|
316
441
|
_ts_decorate([
|
|
317
|
-
|
|
442
|
+
createEndpointDecorators(security.getByIds, 'getByIds', options.enabledEndpoints),
|
|
443
|
+
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
444
|
+
(0, _common.Post)('get-by-ids'),
|
|
445
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
446
|
+
(0, _swagger.ApiOperation)({
|
|
447
|
+
summary: 'Get items by IDs',
|
|
448
|
+
description: 'Retrieves multiple items by their IDs. Optionally specify fields to select.'
|
|
449
|
+
}),
|
|
450
|
+
(0, _swagger.ApiBody)({
|
|
451
|
+
type: _dtos.GetByIdsDto
|
|
452
|
+
}),
|
|
453
|
+
(0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass, true, 'list'),
|
|
454
|
+
_ts_param(0, (0, _common.Body)()),
|
|
455
|
+
_ts_param(1, (0, _decorators.CurrentUser)()),
|
|
456
|
+
_ts_metadata("design:type", Function),
|
|
457
|
+
_ts_metadata("design:paramtypes", [
|
|
458
|
+
typeof _dtos.GetByIdsDto === "undefined" ? Object : _dtos.GetByIdsDto,
|
|
459
|
+
Object
|
|
460
|
+
]),
|
|
461
|
+
_ts_metadata("design:returntype", Promise)
|
|
462
|
+
], ApiController.prototype, "getByIds", null);
|
|
463
|
+
_ts_decorate([
|
|
464
|
+
createEndpointDecorators(security.update, 'update', options.enabledEndpoints),
|
|
318
465
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
319
466
|
(0, _common.Post)('update'),
|
|
320
467
|
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
@@ -337,7 +484,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
337
484
|
_ts_metadata("design:returntype", Promise)
|
|
338
485
|
], ApiController.prototype, "update", null);
|
|
339
486
|
_ts_decorate([
|
|
340
|
-
|
|
487
|
+
createEndpointDecorators(security.updateMany, 'updateMany', options.enabledEndpoints),
|
|
341
488
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
342
489
|
(0, _common.Post)('update-many'),
|
|
343
490
|
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
@@ -361,7 +508,56 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
361
508
|
_ts_metadata("design:returntype", Promise)
|
|
362
509
|
], ApiController.prototype, "updateMany", null);
|
|
363
510
|
_ts_decorate([
|
|
364
|
-
|
|
511
|
+
createEndpointDecorators(security.bulkUpsert, 'bulkUpsert', options.enabledEndpoints),
|
|
512
|
+
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
513
|
+
(0, _common.Post)('bulk-upsert'),
|
|
514
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
515
|
+
(0, _swagger.ApiOperation)({
|
|
516
|
+
summary: 'Create or update multiple items',
|
|
517
|
+
description: 'Bulk upsert: items without ID are created, items with ID are updated.'
|
|
518
|
+
}),
|
|
519
|
+
(0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass, true, 'bulk'),
|
|
520
|
+
(0, _swagger.ApiBody)({
|
|
521
|
+
type: createDtoClass,
|
|
522
|
+
isArray: true
|
|
523
|
+
}),
|
|
524
|
+
(0, _common.UseInterceptors)(_interceptors.SetCreatedByOnBody, _interceptors.SetUpdateByOnBody, _interceptors.Slug),
|
|
525
|
+
_ts_param(0, (0, _common.Body)()),
|
|
526
|
+
_ts_param(1, (0, _decorators.CurrentUser)()),
|
|
527
|
+
_ts_metadata("design:type", Function),
|
|
528
|
+
_ts_metadata("design:paramtypes", [
|
|
529
|
+
Array,
|
|
530
|
+
Object
|
|
531
|
+
]),
|
|
532
|
+
_ts_metadata("design:returntype", Promise)
|
|
533
|
+
], ApiController.prototype, "bulkUpsert", null);
|
|
534
|
+
_ts_decorate([
|
|
535
|
+
createEndpointDecorators(security.getByFilter, 'getByFilter', options.enabledEndpoints),
|
|
536
|
+
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
537
|
+
(0, _common.Post)('get-by-filter'),
|
|
538
|
+
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
539
|
+
(0, _swagger.ApiOperation)({
|
|
540
|
+
summary: 'Get single item by filter',
|
|
541
|
+
description: 'Retrieves a single item matching the provided filter criteria. Returns first match if multiple exist.'
|
|
542
|
+
}),
|
|
543
|
+
(0, _swagger.ApiBody)({
|
|
544
|
+
schema: {
|
|
545
|
+
type: 'object',
|
|
546
|
+
description: 'Filter criteria'
|
|
547
|
+
}
|
|
548
|
+
}),
|
|
549
|
+
(0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass),
|
|
550
|
+
_ts_param(0, (0, _common.Body)()),
|
|
551
|
+
_ts_param(1, (0, _decorators.CurrentUser)()),
|
|
552
|
+
_ts_metadata("design:type", Function),
|
|
553
|
+
_ts_metadata("design:paramtypes", [
|
|
554
|
+
typeof Record === "undefined" ? Object : Record,
|
|
555
|
+
Object
|
|
556
|
+
]),
|
|
557
|
+
_ts_metadata("design:returntype", Promise)
|
|
558
|
+
], ApiController.prototype, "getByFilter", null);
|
|
559
|
+
_ts_decorate([
|
|
560
|
+
createEndpointDecorators(security.getAll, 'getAll', options.enabledEndpoints),
|
|
365
561
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
366
562
|
(0, _common.Post)('get-all'),
|
|
367
563
|
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
@@ -390,7 +586,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
|
|
|
390
586
|
_ts_metadata("design:returntype", Promise)
|
|
391
587
|
], ApiController.prototype, "getAll", null);
|
|
392
588
|
_ts_decorate([
|
|
393
|
-
|
|
589
|
+
createEndpointDecorators(security.delete, 'delete', options.enabledEndpoints),
|
|
394
590
|
(0, _common.Version)(_common.VERSION_NEUTRAL),
|
|
395
591
|
(0, _common.Post)('delete'),
|
|
396
592
|
(0, _common.HttpCode)(_common.HttpStatus.OK),
|
|
@@ -8,11 +8,11 @@ Object.defineProperty(exports, "ApiService", {
|
|
|
8
8
|
return ApiService;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const _dtos = require("../dtos");
|
|
12
11
|
const _common = require("@nestjs/common");
|
|
13
|
-
const _constants = require("../constants");
|
|
14
12
|
const _typeorm = require("typeorm");
|
|
13
|
+
const _constants = require("../constants");
|
|
15
14
|
const _logactiondecorator = require("../decorators/log-action.decorator");
|
|
15
|
+
const _dtos = require("../dtos");
|
|
16
16
|
function _define_property(obj, key, value) {
|
|
17
17
|
if (key in obj) {
|
|
18
18
|
Object.defineProperty(obj, key, {
|
|
@@ -84,14 +84,38 @@ let ApiService = class ApiService {
|
|
|
84
84
|
};
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
-
async
|
|
87
|
+
async bulkUpsert(toInsert, toUpdate, user) {
|
|
88
|
+
return this.executeInTransaction('bulkUpsert', async (qr)=>{
|
|
89
|
+
const allResults = [];
|
|
90
|
+
if (toInsert.length > 0) {
|
|
91
|
+
await this.beforeInsertOperation(toInsert, user, qr);
|
|
92
|
+
const insertedEntities = await this.convertRequestDtoToEntity(toInsert, user);
|
|
93
|
+
const insertedSaved = await qr.manager.save(this.repository.target, insertedEntities);
|
|
94
|
+
await this.afterInsertOperation(this.ensureArray(insertedSaved), user, qr);
|
|
95
|
+
allResults.push(...this.ensureArray(insertedSaved));
|
|
96
|
+
}
|
|
97
|
+
if (toUpdate.length > 0) {
|
|
98
|
+
await this.beforeUpdateOperation(toUpdate, user, qr);
|
|
99
|
+
const updatedEntities = await this.convertRequestDtoToEntity(toUpdate, user);
|
|
100
|
+
const updatedSaved = await qr.manager.save(this.repository.target, updatedEntities);
|
|
101
|
+
await this.afterUpdateOperation(this.ensureArray(updatedSaved), user, qr);
|
|
102
|
+
allResults.push(...this.ensureArray(updatedSaved));
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
saved: allResults,
|
|
106
|
+
returnFirst: false
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async findByIds(ids, user, select) {
|
|
88
111
|
await this.ensureRepositoryInitialized();
|
|
89
112
|
try {
|
|
90
113
|
const query = this.repository.createQueryBuilder(this.entityName);
|
|
91
114
|
query.where({
|
|
92
115
|
id: (0, _typeorm.In)(ids)
|
|
93
116
|
});
|
|
94
|
-
const
|
|
117
|
+
const selectArray = typeof select === 'string' ? select.split(',').map((s)=>s.trim()) : select;
|
|
118
|
+
const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user, selectArray);
|
|
95
119
|
let output;
|
|
96
120
|
if (isRaw) {
|
|
97
121
|
output = await finalQuery.getRawMany();
|
|
@@ -493,6 +517,18 @@ _ts_decorate([
|
|
|
493
517
|
]),
|
|
494
518
|
_ts_metadata("design:returntype", Promise)
|
|
495
519
|
], ApiService.prototype, "updateMany", null);
|
|
520
|
+
_ts_decorate([
|
|
521
|
+
(0, _logactiondecorator.LogAction)({
|
|
522
|
+
action: 'bulkUpsert'
|
|
523
|
+
}),
|
|
524
|
+
_ts_metadata("design:type", Function),
|
|
525
|
+
_ts_metadata("design:paramtypes", [
|
|
526
|
+
Array,
|
|
527
|
+
Array,
|
|
528
|
+
Object
|
|
529
|
+
]),
|
|
530
|
+
_ts_metadata("design:returntype", Promise)
|
|
531
|
+
], ApiService.prototype, "bulkUpsert", null);
|
|
496
532
|
_ts_decorate([
|
|
497
533
|
(0, _logactiondecorator.LogAction)({
|
|
498
534
|
action: 'delete'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "GetByIdsDto", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return GetByIdsDto;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _swagger = require("@nestjs/swagger");
|
|
12
|
+
const _classvalidator = require("class-validator");
|
|
13
|
+
function _define_property(obj, key, value) {
|
|
14
|
+
if (key in obj) {
|
|
15
|
+
Object.defineProperty(obj, key, {
|
|
16
|
+
value: value,
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true
|
|
20
|
+
});
|
|
21
|
+
} else {
|
|
22
|
+
obj[key] = value;
|
|
23
|
+
}
|
|
24
|
+
return obj;
|
|
25
|
+
}
|
|
26
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
27
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
28
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
29
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
30
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31
|
+
}
|
|
32
|
+
function _ts_metadata(k, v) {
|
|
33
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
34
|
+
}
|
|
35
|
+
let GetByIdsDto = class GetByIdsDto {
|
|
36
|
+
constructor(){
|
|
37
|
+
_define_property(this, "ids", void 0);
|
|
38
|
+
_define_property(this, "select", void 0);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
_ts_decorate([
|
|
42
|
+
(0, _swagger.ApiProperty)({
|
|
43
|
+
description: 'Array of IDs to retrieve',
|
|
44
|
+
type: [
|
|
45
|
+
String
|
|
46
|
+
],
|
|
47
|
+
example: [
|
|
48
|
+
'uuid-1',
|
|
49
|
+
'uuid-2'
|
|
50
|
+
]
|
|
51
|
+
}),
|
|
52
|
+
(0, _classvalidator.IsNotEmpty)(),
|
|
53
|
+
(0, _classvalidator.IsArray)(),
|
|
54
|
+
(0, _classvalidator.IsUUID)('all', {
|
|
55
|
+
each: true
|
|
56
|
+
}),
|
|
57
|
+
_ts_metadata("design:type", Array)
|
|
58
|
+
], GetByIdsDto.prototype, "ids", void 0);
|
|
59
|
+
_ts_decorate([
|
|
60
|
+
(0, _swagger.ApiPropertyOptional)({
|
|
61
|
+
description: 'Select specific fields to return (comma-separated or array)'
|
|
62
|
+
}),
|
|
63
|
+
(0, _classvalidator.IsOptional)(),
|
|
64
|
+
_ts_metadata("design:type", Object)
|
|
65
|
+
], GetByIdsDto.prototype, "select", void 0);
|
package/cjs/dtos/index.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./delete.dto"), exports);
|
|
6
6
|
_export_star(require("./filter-and-pagination.dto"), exports);
|
|
7
|
+
_export_star(require("./get-by-ids.dto"), exports);
|
|
7
8
|
_export_star(require("./identity-response.dto"), exports);
|
|
8
9
|
_export_star(require("./pagination.dto"), exports);
|
|
9
10
|
_export_star(require("./response-payload.dto"), exports);
|
package/cjs/entities/index.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./identity"), exports);
|
|
6
|
+
_export_star(require("./raw-type"), exports);
|
|
6
7
|
_export_star(require("./user-root"), exports);
|
|
7
8
|
function _export_star(from, to) {
|
|
8
9
|
Object.keys(from).forEach(function(k) {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Type } from '@nestjs/common';
|
|
2
|
+
import { BulkResponseDto, DeleteDto, FilterAndPaginationDto, GetByIdBodyDto, GetByIdsDto, ListResponseDto, MessageResponseDto, SingleResponseDto } from '../dtos';
|
|
2
3
|
import { Identity } from '../entities';
|
|
3
4
|
import { ILoggedUserInfo, IPermissionLogic, IService } from '../interfaces';
|
|
4
|
-
|
|
5
|
-
export type ApiEndpoint = 'insert' | 'insertMany' | 'getById' | 'getAll' | 'update' | 'updateMany' | 'delete';
|
|
5
|
+
export type ApiEndpoint = 'insert' | 'insertMany' | 'getById' | 'getByIds' | 'getAll' | 'bulkUpsert' | 'getByFilter' | 'update' | 'updateMany' | 'delete';
|
|
6
6
|
export type SecurityLevel = 'public' | 'jwt' | 'permission';
|
|
7
7
|
export interface EndpointSecurity {
|
|
8
8
|
level: SecurityLevel;
|
|
@@ -16,16 +16,22 @@ export type ApiSecurityConfig = {
|
|
|
16
16
|
export interface ApiControllerOptions {
|
|
17
17
|
security?: ApiSecurityConfig | EndpointSecurity | SecurityLevel;
|
|
18
18
|
entityName?: string;
|
|
19
|
+
enabledEndpoints?: ApiEndpoint[] | 'all';
|
|
19
20
|
}
|
|
20
21
|
export declare function createApiController<CreateDtoT extends object, UpdateDtoT extends {
|
|
21
22
|
id: string;
|
|
22
23
|
}, ResponseDtoT extends object, InterfaceT extends Identity, ServiceT extends IService<CreateDtoT, UpdateDtoT, InterfaceT>>(createDtoClass: Type<CreateDtoT>, updateDtoClass: Type<UpdateDtoT>, responseDtoClass: Type<ResponseDtoT>, options?: ApiControllerOptions): abstract new (service: ServiceT) => {
|
|
24
|
+
readonly enabledEndpoints: ApiEndpoint[] | "all";
|
|
23
25
|
service: ServiceT;
|
|
26
|
+
isEnabled(endpoint: ApiEndpoint): boolean;
|
|
24
27
|
insert(addDto: CreateDtoT, user: ILoggedUserInfo | null): Promise<SingleResponseDto<ResponseDtoT>>;
|
|
25
28
|
insertMany(addDto: CreateDtoT[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<ResponseDtoT>>;
|
|
26
29
|
getById(id: string, body: GetByIdBodyDto, user: ILoggedUserInfo | null): Promise<SingleResponseDto<ResponseDtoT>>;
|
|
30
|
+
getByIds(body: GetByIdsDto, user: ILoggedUserInfo | null): Promise<ListResponseDto<ResponseDtoT>>;
|
|
27
31
|
update(updateDto: UpdateDtoT, user: ILoggedUserInfo | null): Promise<SingleResponseDto<ResponseDtoT>>;
|
|
28
32
|
updateMany(updateDtos: UpdateDtoT[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<ResponseDtoT>>;
|
|
33
|
+
bulkUpsert(dtos: (CreateDtoT | UpdateDtoT)[], user: ILoggedUserInfo | null): Promise<BulkResponseDto<ResponseDtoT>>;
|
|
34
|
+
getByFilter(filter: Record<string, any>, user: ILoggedUserInfo | null): Promise<SingleResponseDto<ResponseDtoT>>;
|
|
29
35
|
getAll(filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null, search?: string): Promise<ListResponseDto<ResponseDtoT>>;
|
|
30
36
|
delete(deleteDto: DeleteDto, user: ILoggedUserInfo | null): Promise<MessageResponseDto>;
|
|
31
37
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { QueryRunner, Repository, SelectQueryBuilder } from 'typeorm';
|
|
1
2
|
import { DeleteDto, FilterAndPaginationDto } from '../dtos';
|
|
2
|
-
import { Identity } from '../entities';
|
|
3
|
+
import { Identity, RawEntity } from '../entities';
|
|
3
4
|
import { ILoggedUserInfo, IService } from '../interfaces';
|
|
4
5
|
import { UtilsService } from '../modules/utils/utils.service';
|
|
5
|
-
import { QueryRunner, Repository, SelectQueryBuilder } from 'typeorm';
|
|
6
6
|
import { HybridCache } from './hybrid-cache.class';
|
|
7
7
|
export declare abstract class ApiService<CreateDtoT extends object, UpdateDtoT extends {
|
|
8
8
|
id: string;
|
|
@@ -19,7 +19,8 @@ export declare abstract class ApiService<CreateDtoT extends object, UpdateDtoT e
|
|
|
19
19
|
insertMany(dtos: Array<CreateDtoT>, user: ILoggedUserInfo | null): Promise<InterfaceT[]>;
|
|
20
20
|
update(dto: UpdateDtoT, user: ILoggedUserInfo | null): Promise<InterfaceT>;
|
|
21
21
|
updateMany(dtos: UpdateDtoT[], user: ILoggedUserInfo | null): Promise<InterfaceT[]>;
|
|
22
|
-
|
|
22
|
+
bulkUpsert(toInsert: CreateDtoT[], toUpdate: UpdateDtoT[], user: ILoggedUserInfo | null): Promise<InterfaceT[]>;
|
|
23
|
+
findByIds(ids: string[], user: ILoggedUserInfo | null, select?: string[] | string): Promise<InterfaceT[]>;
|
|
23
24
|
findById(id: string, user: ILoggedUserInfo | null, select?: string[]): Promise<InterfaceT>;
|
|
24
25
|
getAll(search: string, filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
|
|
25
26
|
data: Array<InterfaceT>;
|
|
@@ -63,7 +64,7 @@ export declare abstract class ApiService<CreateDtoT extends object, UpdateDtoT e
|
|
|
63
64
|
protected convertRequestDtoToEntity(dto: CreateDtoT | UpdateDtoT | Array<CreateDtoT | UpdateDtoT>, user: ILoggedUserInfo | null): Promise<Array<EntityT>>;
|
|
64
65
|
protected convertSingleDtoToEntity(dto: CreateDtoT | UpdateDtoT, _user: ILoggedUserInfo | null): Promise<EntityT>;
|
|
65
66
|
protected convertArrayDtoToEntities(dtos: Array<CreateDtoT | UpdateDtoT>, user: ILoggedUserInfo | null): Promise<Array<EntityT>>;
|
|
66
|
-
protected convertEntityToResponseDto(entity: EntityT, _isRaw: boolean): InterfaceT;
|
|
67
|
-
protected convertEntityListToResponseListDto(entities: EntityT[], _isRaw: boolean): InterfaceT[];
|
|
67
|
+
protected convertEntityToResponseDto(entity: EntityT | RawEntity, _isRaw: boolean): InterfaceT;
|
|
68
|
+
protected convertEntityListToResponseListDto(entities: EntityT[] | RawEntity[], _isRaw: boolean): InterfaceT[];
|
|
68
69
|
protected getEntityClass(): Promise<EntityT>;
|
|
69
70
|
}
|
package/dtos/index.d.ts
CHANGED
package/entities/index.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type RawEntity = Record<string, unknown>;
|