@flusys/nestjs-shared 4.0.2 → 4.1.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.
@@ -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
- createSecurityDecorators(security.insert),
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
- createSecurityDecorators(security.insertMany),
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
- createSecurityDecorators(security.getById),
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
- createSecurityDecorators(security.update),
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
- createSecurityDecorators(security.updateMany),
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
- createSecurityDecorators(security.getAll),
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
- createSecurityDecorators(security.delete),
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 findByIds(ids, user) {
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 { query: finalQuery, isRaw } = await this.getSelectQuery(query, user);
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();
@@ -427,7 +451,7 @@ let ApiService = class ApiService {
427
451
  return Object.assign({}, entity);
428
452
  }
429
453
  convertEntityListToResponseListDto(entities, _isRaw) {
430
- return entities.map((entity)=>Object.assign({}, entity));
454
+ return entities.map((entity)=>this.convertEntityToResponseDto(entity, _isRaw));
431
455
  }
432
456
  async getEntityClass() {
433
457
  return await this.repository.create();
@@ -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);
@@ -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) {
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
@@ -1,8 +1,8 @@
1
- import { BulkResponseDto, DeleteDto, FilterAndPaginationDto, GetByIdBodyDto, ListResponseDto, MessageResponseDto, SingleResponseDto } from '../dtos';
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
- import { Type } from '@nestjs/common';
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
- findByIds(ids: string[], user: ILoggedUserInfo | null): Promise<InterfaceT[]>;
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
  }
@@ -0,0 +1,4 @@
1
+ export declare class GetByIdsDto {
2
+ ids: string[];
3
+ select?: string[] | string;
4
+ }
package/dtos/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './delete.dto';
2
2
  export * from './filter-and-pagination.dto';
3
+ export * from './get-by-ids.dto';
3
4
  export * from './identity-response.dto';
4
5
  export * from './pagination.dto';
5
6
  export * from './response-payload.dto';
@@ -1,2 +1,3 @@
1
1
  export * from './identity';
2
+ export * from './raw-type';
2
3
  export * from './user-root';
@@ -0,0 +1 @@
1
+ export type RawEntity = Record<string, unknown>;