@flusys/nestjs-shared 1.1.0 → 1.2.0-rc.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.
Files changed (158) hide show
  1. package/README.md +139 -1103
  2. package/cjs/classes/api-controller.class.js +320 -29
  3. package/cjs/classes/api-service.class.js +219 -64
  4. package/cjs/classes/handle-custome-db.js +37 -0
  5. package/cjs/classes/index.js +1 -2
  6. package/cjs/classes/winston.logger.class.js +103 -70
  7. package/cjs/constants/index.js +1 -4
  8. package/cjs/constants/message-keys.js +68 -0
  9. package/cjs/constants/permissions.js +114 -11
  10. package/cjs/decorators/api-response.decorator.js +1 -2
  11. package/cjs/decorators/index.js +1 -1
  12. package/cjs/decorators/log-action.decorator.js +149 -0
  13. package/cjs/decorators/require-permission.decorator.js +5 -5
  14. package/cjs/dtos/get-by-ids.dto.js +65 -0
  15. package/cjs/dtos/identity-response.dto.js +4 -8
  16. package/cjs/dtos/index.js +1 -0
  17. package/cjs/dtos/response-payload.dto.js +72 -0
  18. package/cjs/entities/identity.js +8 -2
  19. package/cjs/entities/index.js +1 -0
  20. package/cjs/entities/raw-type.js +4 -0
  21. package/cjs/entities/user-root.js +2 -1
  22. package/cjs/enums/index.js +20 -0
  23. package/cjs/enums/notification-type.enum.js +17 -0
  24. package/cjs/enums/participant-status.enum.js +17 -0
  25. package/cjs/enums/recurrence-type.enum.js +18 -0
  26. package/cjs/exceptions/base-app.exception.js +151 -0
  27. package/cjs/exceptions/index.js +1 -0
  28. package/cjs/exceptions/permission.exception.js +13 -9
  29. package/cjs/filters/global-exception.filter.js +279 -0
  30. package/cjs/filters/index.js +18 -0
  31. package/cjs/guards/jwt-auth.guard.js +4 -1
  32. package/cjs/guards/permission.guard.js +71 -77
  33. package/cjs/index.js +2 -0
  34. package/cjs/interceptors/idempotency.interceptor.js +1 -1
  35. package/cjs/interceptors/index.js +0 -1
  36. package/cjs/interfaces/event-manager-adapter.interface.js +11 -0
  37. package/cjs/interfaces/index.js +2 -1
  38. package/cjs/interfaces/notification-adapter.interface.js +11 -0
  39. package/cjs/interfaces/permission.interface.js +1 -1
  40. package/cjs/middlewares/logger.middleware.js +83 -26
  41. package/cjs/modules/datasource/index.js +0 -1
  42. package/cjs/modules/datasource/multi-tenant-datasource.service.js +46 -85
  43. package/cjs/modules/utils/utils.service.js +4 -20
  44. package/cjs/utils/date-time.util.js +94 -0
  45. package/cjs/utils/index.js +1 -1
  46. package/cjs/utils/query-helpers.util.js +8 -1
  47. package/cjs/utils/request.util.js +25 -0
  48. package/classes/api-controller.class.d.ts +14 -6
  49. package/classes/api-service.class.d.ts +25 -22
  50. package/classes/handle-custome-db.d.ts +3 -0
  51. package/classes/index.d.ts +1 -2
  52. package/classes/winston.logger.class.d.ts +1 -0
  53. package/constants/index.d.ts +1 -1
  54. package/constants/message-keys.d.ts +45 -0
  55. package/constants/permissions.d.ts +127 -0
  56. package/decorators/api-response.decorator.d.ts +1 -1
  57. package/decorators/current-user.decorator.d.ts +1 -1
  58. package/decorators/index.d.ts +1 -1
  59. package/decorators/log-action.decorator.d.ts +8 -0
  60. package/decorators/require-permission.decorator.d.ts +2 -2
  61. package/dtos/get-by-ids.dto.d.ts +4 -0
  62. package/dtos/index.d.ts +1 -0
  63. package/dtos/response-payload.dto.d.ts +8 -0
  64. package/entities/index.d.ts +1 -0
  65. package/entities/raw-type.d.ts +1 -0
  66. package/enums/index.d.ts +3 -0
  67. package/enums/notification-type.enum.d.ts +6 -0
  68. package/enums/participant-status.enum.d.ts +6 -0
  69. package/enums/recurrence-type.enum.d.ts +7 -0
  70. package/exceptions/base-app.exception.d.ts +41 -0
  71. package/exceptions/index.d.ts +1 -0
  72. package/exceptions/permission.exception.d.ts +2 -2
  73. package/fesm/classes/api-controller.class.js +321 -30
  74. package/fesm/classes/api-service.class.js +222 -67
  75. package/fesm/classes/handle-custome-db.js +19 -0
  76. package/fesm/classes/index.js +1 -2
  77. package/fesm/classes/winston.logger.class.js +100 -68
  78. package/fesm/constants/index.js +2 -1
  79. package/fesm/constants/message-keys.js +49 -0
  80. package/fesm/constants/permissions.js +86 -14
  81. package/fesm/decorators/api-response.decorator.js +2 -20
  82. package/fesm/decorators/index.js +1 -1
  83. package/fesm/decorators/log-action.decorator.js +139 -0
  84. package/fesm/decorators/require-permission.decorator.js +17 -65
  85. package/fesm/dtos/get-by-ids.dto.js +55 -0
  86. package/fesm/dtos/identity-response.dto.js +4 -8
  87. package/fesm/dtos/index.js +1 -0
  88. package/fesm/dtos/response-payload.dto.js +72 -0
  89. package/fesm/entities/identity.js +8 -2
  90. package/fesm/entities/index.js +1 -0
  91. package/fesm/entities/raw-type.js +1 -0
  92. package/fesm/entities/user-root.js +2 -1
  93. package/fesm/enums/index.js +3 -0
  94. package/fesm/enums/notification-type.enum.js +7 -0
  95. package/fesm/enums/participant-status.enum.js +7 -0
  96. package/fesm/enums/recurrence-type.enum.js +8 -0
  97. package/fesm/exceptions/base-app.exception.js +115 -0
  98. package/fesm/exceptions/index.js +1 -0
  99. package/fesm/exceptions/permission.exception.js +16 -18
  100. package/fesm/filters/global-exception.filter.js +269 -0
  101. package/fesm/filters/index.js +1 -0
  102. package/fesm/guards/jwt-auth.guard.js +5 -2
  103. package/fesm/guards/permission.guard.js +73 -79
  104. package/fesm/index.js +2 -0
  105. package/fesm/interceptors/idempotency.interceptor.js +2 -2
  106. package/fesm/interceptors/index.js +0 -1
  107. package/fesm/interfaces/datasource.interface.js +1 -20
  108. package/fesm/interfaces/event-manager-adapter.interface.js +1 -0
  109. package/fesm/interfaces/index.js +2 -1
  110. package/fesm/interfaces/notification-adapter.interface.js +1 -0
  111. package/fesm/interfaces/permission.interface.js +1 -3
  112. package/fesm/middlewares/logger.middleware.js +83 -26
  113. package/fesm/modules/datasource/index.js +0 -1
  114. package/fesm/modules/datasource/multi-tenant-datasource.service.js +47 -86
  115. package/fesm/modules/utils/utils.service.js +5 -21
  116. package/fesm/utils/date-time.util.js +70 -0
  117. package/fesm/utils/index.js +1 -1
  118. package/fesm/utils/query-helpers.util.js +8 -1
  119. package/fesm/utils/request.util.js +22 -0
  120. package/filters/global-exception.filter.d.ts +9 -0
  121. package/filters/index.d.ts +1 -0
  122. package/guards/permission.guard.d.ts +3 -7
  123. package/index.d.ts +2 -0
  124. package/interceptors/idempotency.interceptor.d.ts +1 -1
  125. package/interceptors/index.d.ts +0 -1
  126. package/interfaces/api.interface.d.ts +2 -0
  127. package/interfaces/event-manager-adapter.interface.d.ts +43 -0
  128. package/interfaces/index.d.ts +2 -1
  129. package/interfaces/notification-adapter.interface.d.ts +21 -0
  130. package/interfaces/permission.interface.d.ts +13 -8
  131. package/modules/datasource/index.d.ts +0 -1
  132. package/modules/datasource/multi-tenant-datasource.service.d.ts +5 -15
  133. package/modules/utils/utils.service.d.ts +0 -1
  134. package/package.json +21 -14
  135. package/utils/date-time.util.d.ts +8 -0
  136. package/utils/index.d.ts +1 -1
  137. package/utils/request.util.d.ts +2 -0
  138. package/cjs/classes/request-scoped-api.service.js +0 -61
  139. package/cjs/classes/winston-logger-adapter.class.js +0 -104
  140. package/cjs/decorators/sanitize-html.decorator.js +0 -36
  141. package/cjs/interceptors/query-performance.interceptor.js +0 -66
  142. package/cjs/interfaces/logger.interface.js +0 -7
  143. package/cjs/modules/datasource/datasource.module.js +0 -117
  144. package/cjs/utils/error-handler.util.js +0 -90
  145. package/classes/request-scoped-api.service.d.ts +0 -14
  146. package/classes/winston-logger-adapter.class.d.ts +0 -22
  147. package/decorators/sanitize-html.decorator.d.ts +0 -2
  148. package/fesm/classes/request-scoped-api.service.js +0 -51
  149. package/fesm/classes/winston-logger-adapter.class.js +0 -107
  150. package/fesm/decorators/sanitize-html.decorator.js +0 -45
  151. package/fesm/interceptors/query-performance.interceptor.js +0 -56
  152. package/fesm/interfaces/logger.interface.js +0 -4
  153. package/fesm/modules/datasource/datasource.module.js +0 -107
  154. package/fesm/utils/error-handler.util.js +0 -82
  155. package/interceptors/query-performance.interceptor.d.ts +0 -8
  156. package/interfaces/logger.interface.d.ts +0 -7
  157. package/modules/datasource/datasource.module.d.ts +0 -19
  158. package/utils/error-handler.util.d.ts +0 -19
@@ -8,14 +8,16 @@ 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 _messagekeys = require("../constants/message-keys");
15
+ const _decorators = require("../decorators");
18
16
  const _apiresponsedecorator = require("../decorators/api-response.decorator");
17
+ const _dtos = require("../dtos");
18
+ const _exceptions = require("../exceptions");
19
+ const _guards = require("../guards");
20
+ const _interceptors = require("../interceptors");
19
21
  function _define_property(obj, key, value) {
20
22
  if (key in obj) {
21
23
  Object.defineProperty(obj, key, {
@@ -54,6 +56,24 @@ function _ts_param(paramIndex, decorator) {
54
56
  };
55
57
  return config;
56
58
  }
59
+ /**
60
+ * Helper to check if endpoint is enabled
61
+ */ function isEndpointEnabled(endpoint, enabledEndpoints) {
62
+ if (!enabledEndpoints || enabledEndpoints === 'all') return true;
63
+ return enabledEndpoints.includes(endpoint);
64
+ }
65
+ /**
66
+ * Helper to conditionally exclude endpoint from Swagger if disabled
67
+ */ function createEndpointDecorators(security, endpoint, enabledEndpoints) {
68
+ const decorators = [];
69
+ // Add security decorators
70
+ decorators.push(createSecurityDecorators(security));
71
+ // Exclude from Swagger if endpoint is disabled
72
+ if (!isEndpointEnabled(endpoint, enabledEndpoints)) {
73
+ decorators.push((0, _swagger.ApiExcludeEndpoint)());
74
+ }
75
+ return (0, _common.applyDecorators)(...decorators);
76
+ }
57
77
  /**
58
78
  * Creates security decorators based on configuration
59
79
  */ function createSecurityDecorators(security) {
@@ -72,11 +92,11 @@ function _ts_param(paramIndex, decorator) {
72
92
  // Apply PermissionGuard to check permissions from cache
73
93
  decorators.push((0, _common.UseGuards)(_guards.JwtAuthGuard, _guards.PermissionGuard));
74
94
  decorators.push((0, _swagger.ApiBearerAuth)());
75
- // Check for complex nested condition first
76
- if (security.condition) {
77
- decorators.push((0, _decorators.RequirePermissionCondition)(security.condition));
95
+ // Check for complex logic first
96
+ if (security.logic) {
97
+ decorators.push((0, _decorators.RequirePermissionLogic)(security.logic));
78
98
  } else if (security.permissions && security.permissions.length > 0) {
79
- if (security.operator === 'or') {
99
+ if (security.operator === 'OR') {
80
100
  decorators.push((0, _decorators.RequireAnyPermission)(...security.permissions));
81
101
  } else {
82
102
  // AND is default and most secure
@@ -88,13 +108,24 @@ function _ts_param(paramIndex, decorator) {
88
108
  return (0, _common.applyDecorators)(...decorators);
89
109
  }
90
110
  function createApiController(createDtoClass, updateDtoClass, responseDtoClass, options = {}) {
111
+ const excludeExtraneousValues = options.excludeExtraneousValues ?? true;
112
+ function toDto(cls, input) {
113
+ return (0, _classtransformer.plainToInstance)(cls, input, {
114
+ excludeExtraneousValues
115
+ });
116
+ }
117
+ // Entity name for message keys (defaults to 'item')
118
+ const entityName = options.entityName ?? 'item';
91
119
  // Determine if security is global (applies to all) or per-endpoint
92
120
  const securityConfig = options.security;
93
121
  const endpointKeys = [
94
122
  'insert',
95
123
  'insertMany',
96
124
  'getById',
125
+ 'getByIds',
97
126
  'getAll',
127
+ 'bulkUpsert',
128
+ 'getByFilter',
98
129
  'update',
99
130
  'updateMany',
100
131
  'delete'
@@ -113,27 +144,59 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
113
144
  insert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insert),
114
145
  insertMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.insertMany),
115
146
  getById: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getById),
147
+ getByIds: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByIds),
116
148
  getAll: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getAll),
149
+ getByFilter: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.getByFilter),
150
+ bulkUpsert: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.bulkUpsert),
117
151
  update: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.update),
118
152
  updateMany: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.updateMany),
119
153
  delete: isGlobalSecurity ? defaultSecurity : normalizeSecurity(securityConfig?.delete)
120
154
  };
121
155
  let ApiController = class ApiController {
156
+ isEnabled(endpoint) {
157
+ if (this.enabledEndpoints === 'all') return true;
158
+ return Array.isArray(this.enabledEndpoints) && this.enabledEndpoints.includes(endpoint);
159
+ }
122
160
  async insert(addDto, user) {
161
+ if (!this.isEnabled('insert')) {
162
+ throw new _exceptions.BaseAppException({
163
+ message: `Endpoint 'insert' is disabled`,
164
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
165
+ messageVariables: {
166
+ endpoint: 'insert'
167
+ },
168
+ status: _common.HttpStatus.FORBIDDEN
169
+ });
170
+ }
123
171
  const entity = await this.service.insert(addDto, user);
124
- const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
172
+ const data = toDto(responseDtoClass, entity);
125
173
  return {
126
174
  success: true,
127
- message: 'Item created successfully',
175
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} created successfully`,
176
+ messageKey: `${entityName}.create.success`,
128
177
  data
129
178
  };
130
179
  }
131
180
  async insertMany(addDto, user) {
181
+ if (!this.isEnabled('insertMany')) {
182
+ throw new _exceptions.BaseAppException({
183
+ message: `Endpoint 'insertMany' is disabled`,
184
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
185
+ messageVariables: {
186
+ endpoint: 'insertMany'
187
+ },
188
+ status: _common.HttpStatus.FORBIDDEN
189
+ });
190
+ }
132
191
  const entities = await this.service.insertMany(addDto, user);
133
- const data = entities.map((item)=>(0, _classtransformer.plainToInstance)(responseDtoClass, item));
192
+ const data = entities.map((item)=>toDto(responseDtoClass, item));
134
193
  return {
135
194
  success: true,
136
- message: `${data.length} items created successfully`,
195
+ message: `${data.length} ${entityName}s created successfully`,
196
+ messageKey: `${entityName}.create.many.success`,
197
+ messageVariables: {
198
+ count: data.length
199
+ },
137
200
  data,
138
201
  meta: {
139
202
  count: data.length,
@@ -143,29 +206,92 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
143
206
  };
144
207
  }
145
208
  async getById(id, body, user) {
209
+ if (!this.isEnabled('getById')) {
210
+ throw new _exceptions.BaseAppException({
211
+ message: `Endpoint 'getById' is disabled`,
212
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
213
+ messageVariables: {
214
+ endpoint: 'getById'
215
+ },
216
+ status: _common.HttpStatus.FORBIDDEN
217
+ });
218
+ }
146
219
  const entity = await this.service.findById(id, user, body?.select);
147
- const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
220
+ const data = toDto(responseDtoClass, entity);
148
221
  return {
149
222
  success: true,
150
- message: 'Item retrieved successfully',
223
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} retrieved successfully`,
224
+ messageKey: `${entityName}.get.success`,
151
225
  data
152
226
  };
153
227
  }
228
+ async getByIds(body, user) {
229
+ if (!this.isEnabled('getByIds')) {
230
+ throw new _exceptions.BaseAppException({
231
+ message: `Endpoint 'getByIds' is disabled`,
232
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
233
+ messageVariables: {
234
+ endpoint: 'getByIds'
235
+ },
236
+ status: _common.HttpStatus.FORBIDDEN
237
+ });
238
+ }
239
+ const entities = await this.service.findByIds(body.ids, user, body?.select);
240
+ const data = entities.map((item)=>toDto(responseDtoClass, item));
241
+ return {
242
+ success: true,
243
+ message: `${data.length} ${entityName}${data.length !== 1 ? 's' : ''} retrieved successfully`,
244
+ messageKey: `${entityName}.get.by.ids.success`,
245
+ data,
246
+ meta: {
247
+ total: data.length,
248
+ page: 0,
249
+ pageSize: data.length,
250
+ count: data.length,
251
+ totalPages: 1
252
+ }
253
+ };
254
+ }
154
255
  async update(updateDto, user) {
256
+ if (!this.isEnabled('update')) {
257
+ throw new _exceptions.BaseAppException({
258
+ message: `Endpoint 'update' is disabled`,
259
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
260
+ messageVariables: {
261
+ endpoint: 'update'
262
+ },
263
+ status: _common.HttpStatus.FORBIDDEN
264
+ });
265
+ }
155
266
  const entity = await this.service.update(updateDto, user);
156
- const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entity);
267
+ const data = toDto(responseDtoClass, entity);
157
268
  return {
158
269
  success: true,
159
- message: 'Item updated successfully',
270
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} updated successfully`,
271
+ messageKey: `${entityName}.update.success`,
160
272
  data
161
273
  };
162
274
  }
163
275
  async updateMany(updateDtos, user) {
276
+ if (!this.isEnabled('updateMany')) {
277
+ throw new _exceptions.BaseAppException({
278
+ message: `Endpoint 'updateMany' is disabled`,
279
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
280
+ messageVariables: {
281
+ endpoint: 'updateMany'
282
+ },
283
+ status: _common.HttpStatus.FORBIDDEN
284
+ });
285
+ }
164
286
  const entities = await this.service.updateMany(updateDtos, user);
165
- const data = (0, _classtransformer.plainToInstance)(responseDtoClass, entities);
287
+ const data = entities.map((item)=>toDto(responseDtoClass, item));
166
288
  return {
167
289
  success: true,
168
- message: `${data.length} items updated successfully`,
290
+ message: `${data.length} ${entityName}s updated successfully`,
291
+ messageKey: `${entityName}.update.many.success`,
292
+ messageVariables: {
293
+ count: data.length
294
+ },
169
295
  data,
170
296
  meta: {
171
297
  count: data.length,
@@ -174,15 +300,93 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
174
300
  }
175
301
  };
176
302
  }
303
+ async bulkUpsert(dtos, user) {
304
+ if (!this.isEnabled('bulkUpsert')) {
305
+ throw new _exceptions.BaseAppException({
306
+ message: `Endpoint 'bulkUpsert' is disabled`,
307
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
308
+ messageVariables: {
309
+ endpoint: 'bulkUpsert'
310
+ },
311
+ status: _common.HttpStatus.FORBIDDEN
312
+ });
313
+ }
314
+ const toInsert = [];
315
+ const toUpdate = [];
316
+ for (const dto of dtos){
317
+ if ('id' in dto && dto.id) {
318
+ toUpdate.push(dto);
319
+ } else {
320
+ toInsert.push(dto);
321
+ }
322
+ }
323
+ const allEntities = await this.service.bulkUpsert(toInsert, toUpdate, user);
324
+ const data = allEntities.map((item)=>toDto(responseDtoClass, item));
325
+ return {
326
+ success: true,
327
+ message: `${data.length} ${entityName}s upserted successfully`,
328
+ messageKey: `${entityName}.upsert.many.success`,
329
+ messageVariables: {
330
+ count: data.length
331
+ },
332
+ data,
333
+ meta: {
334
+ count: data.length,
335
+ total: dtos.length,
336
+ failed: dtos.length - data.length
337
+ }
338
+ };
339
+ }
340
+ async getByFilter(filter, user) {
341
+ if (!this.isEnabled('getByFilter')) {
342
+ throw new _exceptions.BaseAppException({
343
+ message: `Endpoint 'getByFilter' is disabled`,
344
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
345
+ messageVariables: {
346
+ endpoint: 'getByFilter'
347
+ },
348
+ status: _common.HttpStatus.FORBIDDEN
349
+ });
350
+ }
351
+ const result = await this.service.getAll('', {
352
+ filter,
353
+ pagination: {
354
+ currentPage: 0,
355
+ pageSize: 1
356
+ }
357
+ }, user);
358
+ if (!result.data || result.data.length === 0) {
359
+ throw new _exceptions.NotFoundException(entityName);
360
+ }
361
+ const entity = result.data[0];
362
+ const data = toDto(responseDtoClass, entity);
363
+ return {
364
+ success: true,
365
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)} retrieved successfully`,
366
+ messageKey: `${entityName}.get.by.filter.success`,
367
+ data
368
+ };
369
+ }
177
370
  async getAll(filterAndPaginationDto, user, search) {
371
+ if (!this.isEnabled('getAll')) {
372
+ throw new _exceptions.BaseAppException({
373
+ message: `Endpoint 'getAll' is disabled`,
374
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
375
+ messageVariables: {
376
+ endpoint: 'getAll'
377
+ },
378
+ status: _common.HttpStatus.FORBIDDEN
379
+ });
380
+ }
178
381
  const result = await this.service.getAll(search ?? '', filterAndPaginationDto, user);
179
- const data = (0, _classtransformer.plainToInstance)(responseDtoClass, result.data);
382
+ const data = result.data.map((item)=>toDto(responseDtoClass, item));
180
383
  const page = filterAndPaginationDto.pagination?.currentPage ?? 0;
181
384
  const pageSize = filterAndPaginationDto.pagination?.pageSize ?? data.length;
182
385
  const totalPages = pageSize > 0 ? Math.ceil(result.total / pageSize) : 1;
183
386
  return {
184
387
  success: true,
185
- message: 'Data retrieved successfully',
388
+ message: `${entityName.charAt(0).toUpperCase() + entityName.slice(1)}s retrieved successfully`,
389
+ messageKey: `${entityName}.get.all.success`,
186
390
  data,
187
391
  meta: {
188
392
  total: result.total,
@@ -195,21 +399,37 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
195
399
  };
196
400
  }
197
401
  async delete(deleteDto, user) {
402
+ if (!this.isEnabled('delete')) {
403
+ throw new _exceptions.BaseAppException({
404
+ message: `Endpoint 'delete' is disabled`,
405
+ messageKey: _messagekeys.ERROR_MESSAGES.ENDPOINT_DISABLED,
406
+ messageVariables: {
407
+ endpoint: 'delete'
408
+ },
409
+ status: _common.HttpStatus.FORBIDDEN
410
+ });
411
+ }
198
412
  await this.service.delete(deleteDto, user);
199
413
  const count = Array.isArray(deleteDto.id) ? deleteDto.id.length : 1;
200
- const action = deleteDto.type === 'restore' ? 'restored' : 'deleted';
414
+ const action = deleteDto.type === 'restore' ? 'restore' : 'delete';
201
415
  return {
202
416
  success: true,
203
- message: `${count} item${count > 1 ? 's' : ''} ${action} successfully`
417
+ message: `${count} ${entityName}${count > 1 ? 's' : ''} ${action}d successfully`,
418
+ messageKey: `${entityName}.${action}.success`,
419
+ messageVariables: {
420
+ count
421
+ }
204
422
  };
205
423
  }
206
424
  constructor(service){
207
425
  _define_property(this, "service", void 0);
426
+ _define_property(this, "enabledEndpoints", void 0);
208
427
  this.service = service;
428
+ this.enabledEndpoints = options.enabledEndpoints ?? 'all';
209
429
  }
210
430
  };
211
431
  _ts_decorate([
212
- createSecurityDecorators(security.insert),
432
+ createEndpointDecorators(security.insert, 'insert', options.enabledEndpoints),
213
433
  (0, _common.Version)(_common.VERSION_NEUTRAL),
214
434
  (0, _common.Post)('insert'),
215
435
  (0, _common.HttpCode)(_common.HttpStatus.CREATED),
@@ -237,7 +457,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
237
457
  _ts_metadata("design:returntype", Promise)
238
458
  ], ApiController.prototype, "insert", null);
239
459
  _ts_decorate([
240
- createSecurityDecorators(security.insertMany),
460
+ createEndpointDecorators(security.insertMany, 'insertMany', options.enabledEndpoints),
241
461
  (0, _common.Version)(_common.VERSION_NEUTRAL),
242
462
  (0, _common.Post)('insert-many'),
243
463
  (0, _common.HttpCode)(_common.HttpStatus.CREATED),
@@ -266,7 +486,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
266
486
  _ts_metadata("design:returntype", Promise)
267
487
  ], ApiController.prototype, "insertMany", null);
268
488
  _ts_decorate([
269
- createSecurityDecorators(security.getById),
489
+ createEndpointDecorators(security.getById, 'getById', options.enabledEndpoints),
270
490
  (0, _common.Version)(_common.VERSION_NEUTRAL),
271
491
  (0, _common.Post)('get/:id'),
272
492
  (0, _common.HttpCode)(_common.HttpStatus.OK),
@@ -296,7 +516,29 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
296
516
  _ts_metadata("design:returntype", Promise)
297
517
  ], ApiController.prototype, "getById", null);
298
518
  _ts_decorate([
299
- createSecurityDecorators(security.update),
519
+ createEndpointDecorators(security.getByIds, 'getByIds', options.enabledEndpoints),
520
+ (0, _common.Version)(_common.VERSION_NEUTRAL),
521
+ (0, _common.Post)('get-by-ids'),
522
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
523
+ (0, _swagger.ApiOperation)({
524
+ summary: 'Get items by IDs',
525
+ description: 'Retrieves multiple items by their IDs. Optionally specify fields to select.'
526
+ }),
527
+ (0, _swagger.ApiBody)({
528
+ type: _dtos.GetByIdsDto
529
+ }),
530
+ (0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass, true, 'list'),
531
+ _ts_param(0, (0, _common.Body)()),
532
+ _ts_param(1, (0, _decorators.CurrentUser)()),
533
+ _ts_metadata("design:type", Function),
534
+ _ts_metadata("design:paramtypes", [
535
+ typeof _dtos.GetByIdsDto === "undefined" ? Object : _dtos.GetByIdsDto,
536
+ Object
537
+ ]),
538
+ _ts_metadata("design:returntype", Promise)
539
+ ], ApiController.prototype, "getByIds", null);
540
+ _ts_decorate([
541
+ createEndpointDecorators(security.update, 'update', options.enabledEndpoints),
300
542
  (0, _common.Version)(_common.VERSION_NEUTRAL),
301
543
  (0, _common.Post)('update'),
302
544
  (0, _common.HttpCode)(_common.HttpStatus.OK),
@@ -319,7 +561,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
319
561
  _ts_metadata("design:returntype", Promise)
320
562
  ], ApiController.prototype, "update", null);
321
563
  _ts_decorate([
322
- createSecurityDecorators(security.updateMany),
564
+ createEndpointDecorators(security.updateMany, 'updateMany', options.enabledEndpoints),
323
565
  (0, _common.Version)(_common.VERSION_NEUTRAL),
324
566
  (0, _common.Post)('update-many'),
325
567
  (0, _common.HttpCode)(_common.HttpStatus.OK),
@@ -343,7 +585,56 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
343
585
  _ts_metadata("design:returntype", Promise)
344
586
  ], ApiController.prototype, "updateMany", null);
345
587
  _ts_decorate([
346
- createSecurityDecorators(security.getAll),
588
+ createEndpointDecorators(security.bulkUpsert, 'bulkUpsert', options.enabledEndpoints),
589
+ (0, _common.Version)(_common.VERSION_NEUTRAL),
590
+ (0, _common.Post)('bulk-upsert'),
591
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
592
+ (0, _swagger.ApiOperation)({
593
+ summary: 'Create or update multiple items',
594
+ description: 'Bulk upsert: items without ID are created, items with ID are updated.'
595
+ }),
596
+ (0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass, true, 'bulk'),
597
+ (0, _swagger.ApiBody)({
598
+ type: createDtoClass,
599
+ isArray: true
600
+ }),
601
+ (0, _common.UseInterceptors)(_interceptors.SetCreatedByOnBody, _interceptors.SetUpdateByOnBody, _interceptors.Slug),
602
+ _ts_param(0, (0, _common.Body)()),
603
+ _ts_param(1, (0, _decorators.CurrentUser)()),
604
+ _ts_metadata("design:type", Function),
605
+ _ts_metadata("design:paramtypes", [
606
+ Array,
607
+ Object
608
+ ]),
609
+ _ts_metadata("design:returntype", Promise)
610
+ ], ApiController.prototype, "bulkUpsert", null);
611
+ _ts_decorate([
612
+ createEndpointDecorators(security.getByFilter, 'getByFilter', options.enabledEndpoints),
613
+ (0, _common.Version)(_common.VERSION_NEUTRAL),
614
+ (0, _common.Post)('get-by-filter'),
615
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
616
+ (0, _swagger.ApiOperation)({
617
+ summary: 'Get single item by filter',
618
+ description: 'Retrieves a single item matching the provided filter criteria. Returns first match if multiple exist.'
619
+ }),
620
+ (0, _swagger.ApiBody)({
621
+ schema: {
622
+ type: 'object',
623
+ description: 'Filter criteria'
624
+ }
625
+ }),
626
+ (0, _apiresponsedecorator.ApiResponseDto)(responseDtoClass),
627
+ _ts_param(0, (0, _common.Body)()),
628
+ _ts_param(1, (0, _decorators.CurrentUser)()),
629
+ _ts_metadata("design:type", Function),
630
+ _ts_metadata("design:paramtypes", [
631
+ typeof Record === "undefined" ? Object : Record,
632
+ Object
633
+ ]),
634
+ _ts_metadata("design:returntype", Promise)
635
+ ], ApiController.prototype, "getByFilter", null);
636
+ _ts_decorate([
637
+ createEndpointDecorators(security.getAll, 'getAll', options.enabledEndpoints),
347
638
  (0, _common.Version)(_common.VERSION_NEUTRAL),
348
639
  (0, _common.Post)('get-all'),
349
640
  (0, _common.HttpCode)(_common.HttpStatus.OK),
@@ -372,7 +663,7 @@ function createApiController(createDtoClass, updateDtoClass, responseDtoClass, o
372
663
  _ts_metadata("design:returntype", Promise)
373
664
  ], ApiController.prototype, "getAll", null);
374
665
  _ts_decorate([
375
- createSecurityDecorators(security.delete),
666
+ createEndpointDecorators(security.delete, 'delete', options.enabledEndpoints),
376
667
  (0, _common.Version)(_common.VERSION_NEUTRAL),
377
668
  (0, _common.Post)('delete'),
378
669
  (0, _common.HttpCode)(_common.HttpStatus.OK),