@flusys/nestjs-shared 4.0.1 → 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.
@@ -25,14 +25,15 @@ function _ts_param(paramIndex, decorator) {
25
25
  decorator(target, key, paramIndex);
26
26
  };
27
27
  }
28
- import { CurrentUser, Public, RequirePermission, RequireAnyPermission, RequirePermissionLogic } from '../decorators';
29
- import { DeleteDto, FilterAndPaginationDto, GetByIdBodyDto } from '../dtos';
30
- import { JwtAuthGuard, PermissionGuard } from '../guards';
31
- import { IdempotencyInterceptor, SetCreatedByOnBody, SetDeletedByOnBody, SetUpdateByOnBody, Slug } from '../interceptors';
32
28
  import { applyDecorators, Body, HttpCode, HttpStatus, Param, Post, Query, UseGuards, UseInterceptors, Version, VERSION_NEUTRAL } from '@nestjs/common';
33
- import { ApiBearerAuth, ApiBody, ApiHeader, ApiOperation, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
29
+ import { ApiBearerAuth, ApiBody, ApiExcludeEndpoint, ApiHeader, ApiOperation, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';
34
30
  import { plainToInstance } from 'class-transformer';
31
+ import { CurrentUser, Public, RequireAnyPermission, RequirePermission, RequirePermissionLogic } from '../decorators';
35
32
  import { ApiResponseDto } from '../decorators/api-response.decorator';
33
+ import { DeleteDto, FilterAndPaginationDto, GetByIdBodyDto, GetByIdsDto } from '../dtos';
34
+ import { ForbiddenException, NotFoundException } from '../exceptions';
35
+ import { JwtAuthGuard, PermissionGuard } from '../guards';
36
+ import { IdempotencyInterceptor, SetCreatedByOnBody, SetDeletedByOnBody, SetUpdateByOnBody, Slug } from '../interceptors';
36
37
  /**
37
38
  * Helper to normalize security config
38
39
  */ function normalizeSecurity(config) {
@@ -44,6 +45,24 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
44
45
  };
45
46
  return config;
46
47
  }
48
+ /**
49
+ * Helper to check if endpoint is enabled
50
+ */ function isEndpointEnabled(endpoint, enabledEndpoints) {
51
+ if (!enabledEndpoints || enabledEndpoints === 'all') return true;
52
+ return enabledEndpoints.includes(endpoint);
53
+ }
54
+ /**
55
+ * Helper to conditionally exclude endpoint from Swagger if disabled
56
+ */ function createEndpointDecorators(security, endpoint, enabledEndpoints) {
57
+ const decorators = [];
58
+ // Add security decorators
59
+ decorators.push(createSecurityDecorators(security));
60
+ // Exclude from Swagger if endpoint is disabled
61
+ if (!isEndpointEnabled(endpoint, enabledEndpoints)) {
62
+ decorators.push(ApiExcludeEndpoint());
63
+ }
64
+ return applyDecorators(...decorators);
65
+ }
47
66
  /**
48
67
  * Creates security decorators based on configuration
49
68
  */ function createSecurityDecorators(security) {
@@ -86,7 +105,10 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
86
105
  'insert',
87
106
  'insertMany',
88
107
  'getById',
108
+ 'getByIds',
89
109
  'getAll',
110
+ 'bulkUpsert',
111
+ 'getByFilter',
90
112
  'update',
91
113
  'updateMany',
92
114
  'delete'
@@ -105,13 +127,23 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
105
127
  insert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insert),
106
128
  insertMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insertMany),
107
129
  getById: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getById),
130
+ getByIds: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByIds),
108
131
  getAll: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getAll),
132
+ getByFilter: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByFilter),
133
+ bulkUpsert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.bulkUpsert),
109
134
  update: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.update),
110
135
  updateMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.updateMany),
111
136
  delete: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.delete)
112
137
  };
113
138
  let ApiController = class ApiController {
139
+ isEnabled(endpoint) {
140
+ if (this.enabledEndpoints === 'all') return true;
141
+ return Array.isArray(this.enabledEndpoints) && this.enabledEndpoints.includes(endpoint);
142
+ }
114
143
  async insert(addDto, user) {
144
+ if (!this.isEnabled('insert')) {
145
+ throw new ForbiddenException(`Endpoint 'insert' is disabled`);
146
+ }
115
147
  const entity = await this.service.insert(addDto, user);
116
148
  const data = plainToInstance(responseDtoClass, entity);
117
149
  return {
@@ -122,6 +154,9 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
122
154
  };
123
155
  }
124
156
  async insertMany(addDto, user) {
157
+ if (!this.isEnabled('insertMany')) {
158
+ throw new ForbiddenException(`Endpoint 'insertMany' is disabled`);
159
+ }
125
160
  const entities = await this.service.insertMany(addDto, user);
126
161
  const data = entities.map((item)=>plainToInstance(responseDtoClass, item));
127
162
  return {
@@ -140,6 +175,9 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
140
175
  };
141
176
  }
142
177
  async getById(id, body, user) {
178
+ if (!this.isEnabled('getById')) {
179
+ throw new ForbiddenException(`Endpoint 'getById' is disabled`);
180
+ }
143
181
  const entity = await this.service.findById(id, user, body?.select);
144
182
  const data = plainToInstance(responseDtoClass, entity);
145
183
  return {
@@ -149,7 +187,30 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
149
187
  data
150
188
  };
151
189
  }
190
+ async getByIds(body, user) {
191
+ if (!this.isEnabled('getByIds')) {
192
+ throw new ForbiddenException(`Endpoint 'getByIds' is disabled`);
193
+ }
194
+ const entities = await this.service.findByIds(body.ids, user, body?.select);
195
+ const data = plainToInstance(responseDtoClass, entities);
196
+ return {
197
+ success: true,
198
+ message: `${data.length} ${entityName}${data.length !== 1 ? 's' : ''} retrieved successfully`,
199
+ messageKey: `${entityName}.get.by.ids.success`,
200
+ data,
201
+ meta: {
202
+ total: data.length,
203
+ page: 0,
204
+ pageSize: data.length,
205
+ count: data.length,
206
+ totalPages: 1
207
+ }
208
+ };
209
+ }
152
210
  async update(updateDto, user) {
211
+ if (!this.isEnabled('update')) {
212
+ throw new ForbiddenException(`Endpoint 'update' is disabled`);
213
+ }
153
214
  const entity = await this.service.update(updateDto, user);
154
215
  const data = plainToInstance(responseDtoClass, entity);
155
216
  return {
@@ -160,6 +221,9 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
160
221
  };
161
222
  }
162
223
  async updateMany(updateDtos, user) {
224
+ if (!this.isEnabled('updateMany')) {
225
+ throw new ForbiddenException(`Endpoint 'updateMany' is disabled`);
226
+ }
163
227
  const entities = await this.service.updateMany(updateDtos, user);
164
228
  const data = plainToInstance(responseDtoClass, entities);
165
229
  return {
@@ -177,7 +241,63 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
177
241
  }
178
242
  };
179
243
  }
244
+ async bulkUpsert(dtos, user) {
245
+ if (!this.isEnabled('bulkUpsert')) {
246
+ throw new ForbiddenException(`Endpoint 'bulkUpsert' is disabled`);
247
+ }
248
+ const toInsert = [];
249
+ const toUpdate = [];
250
+ for (const dto of dtos){
251
+ if ('id' in dto && dto.id) {
252
+ toUpdate.push(dto);
253
+ } else {
254
+ toInsert.push(dto);
255
+ }
256
+ }
257
+ const allEntities = await this.service.bulkUpsert(toInsert, toUpdate, user);
258
+ const data = plainToInstance(responseDtoClass, allEntities);
259
+ return {
260
+ success: true,
261
+ message: `${data.length} ${entityName}s upserted successfully`,
262
+ messageKey: `${entityName}.upsert.many.success`,
263
+ messageVariables: {
264
+ count: data.length
265
+ },
266
+ data,
267
+ meta: {
268
+ count: data.length,
269
+ total: dtos.length,
270
+ failed: dtos.length - data.length
271
+ }
272
+ };
273
+ }
274
+ async getByFilter(filter, user) {
275
+ if (!this.isEnabled('getByFilter')) {
276
+ throw new ForbiddenException(`Endpoint 'getByFilter' is disabled`);
277
+ }
278
+ const result = await this.service.getAll('', {
279
+ filter,
280
+ pagination: {
281
+ currentPage: 0,
282
+ pageSize: 1
283
+ }
284
+ }, user);
285
+ if (!result.data || result.data.length === 0) {
286
+ throw new NotFoundException(entityName);
287
+ }
288
+ const entity = result.data[0];
289
+ const data = plainToInstance(responseDtoClass, entity);
290
+ return {
291
+ success: true,
292
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} retrieved successfully`,
293
+ messageKey: `${entityName}.get.by.filter.success`,
294
+ data
295
+ };
296
+ }
180
297
  async getAll(filterAndPaginationDto, user, search) {
298
+ if (!this.isEnabled('getAll')) {
299
+ throw new ForbiddenException(`Endpoint 'getAll' is disabled`);
300
+ }
181
301
  const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
182
302
  const data = plainToInstance(responseDtoClass, result.data);
183
303
  const page = filterAndPaginationDto.pagination?.currentPage ?? 0;
@@ -199,6 +319,9 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
199
319
  };
200
320
  }
201
321
  async delete(deleteDto, user) {
322
+ if (!this.isEnabled('delete')) {
323
+ throw new ForbiddenException(`Endpoint 'delete' is disabled`);
324
+ }
202
325
  await this.service.delete(deleteDto, user);
203
326
  const count = Array.isArray(deleteDto.id) ? deleteDto.id.length : 1;
204
327
  const action = deleteDto.type === 'restore' ? 'restore' : 'delete';
@@ -213,11 +336,13 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
213
336
  }
214
337
  constructor(service){
215
338
  _define_property(this, "service", void 0);
339
+ _define_property(this, "enabledEndpoints", void 0);
216
340
  this.service = service;
341
+ this.enabledEndpoints = options.enabledEndpoints ?? 'all';
217
342
  }
218
343
  };
219
344
  _ts_decorate([
220
- createSecurityDecorators(security.insert),
345
+ createEndpointDecorators(security.insert, 'insert', options.enabledEndpoints),
221
346
  Version(VERSION_NEUTRAL),
222
347
  Post('insert'),
223
348
  HttpCode(HttpStatus.CREATED),
@@ -245,7 +370,7 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
245
370
  _ts_metadata("design:returntype", Promise)
246
371
  ], ApiController.prototype, "insert", null);
247
372
  _ts_decorate([
248
- createSecurityDecorators(security.insertMany),
373
+ createEndpointDecorators(security.insertMany, 'insertMany', options.enabledEndpoints),
249
374
  Version(VERSION_NEUTRAL),
250
375
  Post('insert-many'),
251
376
  HttpCode(HttpStatus.CREATED),
@@ -274,7 +399,7 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
274
399
  _ts_metadata("design:returntype", Promise)
275
400
  ], ApiController.prototype, "insertMany", null);
276
401
  _ts_decorate([
277
- createSecurityDecorators(security.getById),
402
+ createEndpointDecorators(security.getById, 'getById', options.enabledEndpoints),
278
403
  Version(VERSION_NEUTRAL),
279
404
  Post('get/:id'),
280
405
  HttpCode(HttpStatus.OK),
@@ -304,7 +429,29 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
304
429
  _ts_metadata("design:returntype", Promise)
305
430
  ], ApiController.prototype, "getById", null);
306
431
  _ts_decorate([
307
- createSecurityDecorators(security.update),
432
+ createEndpointDecorators(security.getByIds, 'getByIds', options.enabledEndpoints),
433
+ Version(VERSION_NEUTRAL),
434
+ Post('get-by-ids'),
435
+ HttpCode(HttpStatus.OK),
436
+ ApiOperation({
437
+ summary: 'Get items by IDs',
438
+ description: 'Retrieves multiple items by their IDs. Optionally specify fields to select.'
439
+ }),
440
+ ApiBody({
441
+ type: GetByIdsDto
442
+ }),
443
+ ApiResponseDto(responseDtoClass, true, 'list'),
444
+ _ts_param(0, Body()),
445
+ _ts_param(1, CurrentUser()),
446
+ _ts_metadata("design:type", Function),
447
+ _ts_metadata("design:paramtypes", [
448
+ typeof GetByIdsDto === "undefined" ? Object : GetByIdsDto,
449
+ Object
450
+ ]),
451
+ _ts_metadata("design:returntype", Promise)
452
+ ], ApiController.prototype, "getByIds", null);
453
+ _ts_decorate([
454
+ createEndpointDecorators(security.update, 'update', options.enabledEndpoints),
308
455
  Version(VERSION_NEUTRAL),
309
456
  Post('update'),
310
457
  HttpCode(HttpStatus.OK),
@@ -327,7 +474,7 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
327
474
  _ts_metadata("design:returntype", Promise)
328
475
  ], ApiController.prototype, "update", null);
329
476
  _ts_decorate([
330
- createSecurityDecorators(security.updateMany),
477
+ createEndpointDecorators(security.updateMany, 'updateMany', options.enabledEndpoints),
331
478
  Version(VERSION_NEUTRAL),
332
479
  Post('update-many'),
333
480
  HttpCode(HttpStatus.OK),
@@ -351,7 +498,56 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
351
498
  _ts_metadata("design:returntype", Promise)
352
499
  ], ApiController.prototype, "updateMany", null);
353
500
  _ts_decorate([
354
- createSecurityDecorators(security.getAll),
501
+ createEndpointDecorators(security.bulkUpsert, 'bulkUpsert', options.enabledEndpoints),
502
+ Version(VERSION_NEUTRAL),
503
+ Post('bulk-upsert'),
504
+ HttpCode(HttpStatus.OK),
505
+ ApiOperation({
506
+ summary: 'Create or update multiple items',
507
+ description: 'Bulk upsert: items without ID are created, items with ID are updated.'
508
+ }),
509
+ ApiResponseDto(responseDtoClass, true, 'bulk'),
510
+ ApiBody({
511
+ type: createDtoClass,
512
+ isArray: true
513
+ }),
514
+ UseInterceptors(SetCreatedByOnBody, SetUpdateByOnBody, Slug),
515
+ _ts_param(0, Body()),
516
+ _ts_param(1, CurrentUser()),
517
+ _ts_metadata("design:type", Function),
518
+ _ts_metadata("design:paramtypes", [
519
+ Array,
520
+ Object
521
+ ]),
522
+ _ts_metadata("design:returntype", Promise)
523
+ ], ApiController.prototype, "bulkUpsert", null);
524
+ _ts_decorate([
525
+ createEndpointDecorators(security.getByFilter, 'getByFilter', options.enabledEndpoints),
526
+ Version(VERSION_NEUTRAL),
527
+ Post('get-by-filter'),
528
+ HttpCode(HttpStatus.OK),
529
+ ApiOperation({
530
+ summary: 'Get single item by filter',
531
+ description: 'Retrieves a single item matching the provided filter criteria. Returns first match if multiple exist.'
532
+ }),
533
+ ApiBody({
534
+ schema: {
535
+ type: 'object',
536
+ description: 'Filter criteria'
537
+ }
538
+ }),
539
+ ApiResponseDto(responseDtoClass),
540
+ _ts_param(0, Body()),
541
+ _ts_param(1, CurrentUser()),
542
+ _ts_metadata("design:type", Function),
543
+ _ts_metadata("design:paramtypes", [
544
+ typeof Record === "undefined" ? Object : Record,
545
+ Object
546
+ ]),
547
+ _ts_metadata("design:returntype", Promise)
548
+ ], ApiController.prototype, "getByFilter", null);
549
+ _ts_decorate([
550
+ createEndpointDecorators(security.getAll, 'getAll', options.enabledEndpoints),
355
551
  Version(VERSION_NEUTRAL),
356
552
  Post('get-all'),
357
553
  HttpCode(HttpStatus.OK),
@@ -380,7 +576,7 @@ import { ApiResponseDto } from '../decorators/api-response.decorator';
380
576
  _ts_metadata("design:returntype", Promise)
381
577
  ], ApiController.prototype, "getAll", null);
382
578
  _ts_decorate([
383
- createSecurityDecorators(security.delete),
579
+ createEndpointDecorators(security.delete, 'delete', options.enabledEndpoints),
384
580
  Version(VERSION_NEUTRAL),
385
581
  Post('delete'),
386
582
  HttpCode(HttpStatus.OK),
@@ -20,11 +20,11 @@ function _ts_decorate(decorators, target, key, desc) {
20
20
  function _ts_metadata(k, v) {
21
21
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
22
  }
23
- import { DeleteDto } from '../dtos';
24
23
  import { InternalServerErrorException, NotFoundException } from '@nestjs/common';
25
- import { SYSTEM_MESSAGES } from '../constants';
26
24
  import { In } from 'typeorm';
25
+ import { SYSTEM_MESSAGES } from '../constants';
27
26
  import { LogAction } from '../decorators/log-action.decorator';
27
+ import { DeleteDto } from '../dtos';
28
28
  /** Generic API service with CRUD operations and caching support */ export class ApiService {
29
29
  async insert(dto, user) {
30
30
  return this.executeInTransaction('insert', async (qr)=>{
@@ -74,14 +74,38 @@ import { LogAction } from '../decorators/log-action.decorator';
74
74
  };
75
75
  });
76
76
  }
77
- async findByIds(ids, user) {
77
+ async bulkUpsert(toInsert, toUpdate, user) {
78
+ return this.executeInTransaction('bulkUpsert', async (qr)=>{
79
+ const allResults = [];
80
+ if (toInsert.length > 0) {
81
+ await this.beforeInsertOperation(toInsert, user, qr);
82
+ const insertedEntities = await this.convertRequestDtoToEntity(toInsert, user);
83
+ const insertedSaved = await qr.manager.save(this.repository.target, insertedEntities);
84
+ await this.afterInsertOperation(this.ensureArray(insertedSaved), user, qr);
85
+ allResults.push(...this.ensureArray(insertedSaved));
86
+ }
87
+ if (toUpdate.length > 0) {
88
+ await this.beforeUpdateOperation(toUpdate, user, qr);
89
+ const updatedEntities = await this.convertRequestDtoToEntity(toUpdate, user);
90
+ const updatedSaved = await qr.manager.save(this.repository.target, updatedEntities);
91
+ await this.afterUpdateOperation(this.ensureArray(updatedSaved), user, qr);
92
+ allResults.push(...this.ensureArray(updatedSaved));
93
+ }
94
+ return {
95
+ saved: allResults,
96
+ returnFirst: false
97
+ };
98
+ });
99
+ }
100
+ async findByIds(ids, user, select) {
78
101
  await this.ensureRepositoryInitialized();
79
102
  try {
80
103
  const query = this.repository.createQueryBuilder(this.entityName);
81
104
  query.where({
82
105
  id: In(ids)
83
106
  });
84
- const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user);
107
+ const selectArray = typeof select === 'string' ? select.split(',').map((s)=>s.trim()) : select;
108
+ const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user, selectArray);
85
109
  let output;
86
110
  if (isRaw) {
87
111
  output = await finalQuery.getRawMany();
@@ -483,6 +507,18 @@ _ts_decorate([
483
507
  ]),
484
508
  _ts_metadata("design:returntype", Promise)
485
509
  ], ApiService.prototype, "updateMany", null);
510
+ _ts_decorate([
511
+ LogAction({
512
+ action: 'bulkUpsert'
513
+ }),
514
+ _ts_metadata("design:type", Function),
515
+ _ts_metadata("design:paramtypes", [
516
+ Array,
517
+ Array,
518
+ Object
519
+ ]),
520
+ _ts_metadata("design:returntype", Promise)
521
+ ], ApiService.prototype, "bulkUpsert", null);
486
522
  _ts_decorate([
487
523
  LogAction({
488
524
  action: 'delete'
@@ -0,0 +1,55 @@
1
+ function _define_property(obj, key, value) {
2
+ if (key in obj) {
3
+ Object.defineProperty(obj, key, {
4
+ value: value,
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true
8
+ });
9
+ } else {
10
+ obj[key] = value;
11
+ }
12
+ return obj;
13
+ }
14
+ function _ts_decorate(decorators, target, key, desc) {
15
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
16
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
17
+ 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;
18
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
19
+ }
20
+ function _ts_metadata(k, v) {
21
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
22
+ }
23
+ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
24
+ import { IsArray, IsNotEmpty, IsOptional, IsUUID } from 'class-validator';
25
+ export class GetByIdsDto {
26
+ constructor(){
27
+ _define_property(this, "ids", void 0);
28
+ _define_property(this, "select", void 0);
29
+ }
30
+ }
31
+ _ts_decorate([
32
+ ApiProperty({
33
+ description: 'Array of IDs to retrieve',
34
+ type: [
35
+ String
36
+ ],
37
+ example: [
38
+ 'uuid-1',
39
+ 'uuid-2'
40
+ ]
41
+ }),
42
+ IsNotEmpty(),
43
+ IsArray(),
44
+ IsUUID('all', {
45
+ each: true
46
+ }),
47
+ _ts_metadata("design:type", Array)
48
+ ], GetByIdsDto.prototype, "ids", void 0);
49
+ _ts_decorate([
50
+ ApiPropertyOptional({
51
+ description: 'Select specific fields to return (comma-separated or array)'
52
+ }),
53
+ IsOptional(),
54
+ _ts_metadata("design:type", Object)
55
+ ], GetByIdsDto.prototype, "select", void 0);
@@ -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 { };
@@ -4,11 +4,13 @@ export interface IService<CreateDtoT, UpdateDtoT, InterfaceT> {
4
4
  insert(addDto: CreateDtoT, user: ILoggedUserInfo | null): Promise<InterfaceT>;
5
5
  insertMany(addDto: Array<CreateDtoT>, user: ILoggedUserInfo | null): Promise<Array<InterfaceT>>;
6
6
  findById(id: string, user: ILoggedUserInfo | null, select?: string[]): Promise<InterfaceT>;
7
+ findByIds(ids: string[], user: ILoggedUserInfo | null, select?: string[] | string): Promise<Array<InterfaceT>>;
7
8
  getAll(search: string, filterAndPaginationDto: FilterAndPaginationDto, user: ILoggedUserInfo | null): Promise<{
8
9
  data: Array<InterfaceT>;
9
10
  total: number;
10
11
  }>;
11
12
  update(updateDto: UpdateDtoT, user: ILoggedUserInfo | null): Promise<InterfaceT>;
12
13
  updateMany(updateDto: Array<UpdateDtoT>, user: ILoggedUserInfo | null): Promise<Array<InterfaceT>>;
14
+ bulkUpsert(toInsert: Array<CreateDtoT>, toUpdate: Array<UpdateDtoT>, user: ILoggedUserInfo | null): Promise<Array<InterfaceT>>;
13
15
  delete(deleteDto: DeleteDto, user: ILoggedUserInfo | null): Promise<null>;
14
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flusys/nestjs-shared",
3
- "version": "4.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "Common shared utilities for Flusys NestJS applications",
5
5
  "main": "cjs/index.js",
6
6
  "module": "fesm/index.js",
@@ -112,6 +112,6 @@
112
112
  "rxjs": "^7.8.0"
113
113
  },
114
114
  "dependencies": {
115
- "@flusys/nestjs-core": "4.0.1"
115
+ "@flusys/nestjs-core": "4.1.0"
116
116
  }
117
117
  }