@flusys/nestjs-shared 1.1.0-beta → 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 (198) hide show
  1. package/README.md +146 -1330
  2. package/cjs/classes/api-controller.class.js +325 -49
  3. package/cjs/classes/api-service.class.js +271 -149
  4. package/cjs/classes/handle-custome-db.js +37 -0
  5. package/cjs/classes/index.js +2 -2
  6. package/cjs/classes/winston.logger.class.js +103 -70
  7. package/cjs/constants/index.js +15 -4
  8. package/cjs/constants/message-keys.js +68 -0
  9. package/cjs/constants/permissions.js +287 -0
  10. package/cjs/decorators/api-response.decorator.js +2 -3
  11. package/cjs/decorators/index.js +1 -0
  12. package/cjs/decorators/log-action.decorator.js +149 -0
  13. package/cjs/decorators/require-permission.decorator.js +5 -5
  14. package/cjs/dtos/delete.dto.js +10 -0
  15. package/cjs/dtos/filter-and-pagination.dto.js +24 -34
  16. package/cjs/dtos/get-by-ids.dto.js +65 -0
  17. package/cjs/dtos/identity-response.dto.js +4 -8
  18. package/cjs/dtos/index.js +1 -0
  19. package/cjs/dtos/pagination.dto.js +4 -8
  20. package/cjs/dtos/response-payload.dto.js +68 -112
  21. package/cjs/entities/identity.js +12 -6
  22. package/cjs/entities/index.js +1 -0
  23. package/cjs/entities/raw-type.js +4 -0
  24. package/cjs/entities/user-root.js +15 -15
  25. package/cjs/enums/index.js +20 -0
  26. package/cjs/enums/notification-type.enum.js +17 -0
  27. package/cjs/enums/participant-status.enum.js +17 -0
  28. package/cjs/enums/recurrence-type.enum.js +18 -0
  29. package/cjs/exceptions/base-app.exception.js +151 -0
  30. package/cjs/exceptions/index.js +1 -0
  31. package/cjs/exceptions/permission.exception.js +13 -9
  32. package/cjs/filters/global-exception.filter.js +279 -0
  33. package/cjs/filters/index.js +18 -0
  34. package/cjs/guards/jwt-auth.guard.js +4 -1
  35. package/cjs/guards/permission.guard.js +88 -148
  36. package/cjs/index.js +2 -0
  37. package/cjs/interceptors/idempotency.interceptor.js +1 -1
  38. package/cjs/interceptors/index.js +1 -4
  39. package/cjs/interceptors/set-user-field-on-body.interceptor.js +60 -0
  40. package/cjs/interceptors/slug.interceptor.js +30 -9
  41. package/cjs/interfaces/datasource.interface.js +4 -0
  42. package/cjs/interfaces/event-manager-adapter.interface.js +11 -0
  43. package/cjs/interfaces/index.js +4 -2
  44. package/cjs/interfaces/module-config.interface.js +4 -0
  45. package/cjs/interfaces/notification-adapter.interface.js +11 -0
  46. package/cjs/interfaces/permission.interface.js +1 -1
  47. package/cjs/middlewares/logger.middleware.js +133 -115
  48. package/cjs/modules/cache/cache.module.js +3 -3
  49. package/cjs/modules/datasource/index.js +0 -1
  50. package/cjs/modules/datasource/multi-tenant-datasource.service.js +60 -183
  51. package/cjs/modules/utils/utils.service.js +27 -206
  52. package/cjs/utils/date-time.util.js +94 -0
  53. package/cjs/utils/html-sanitizer.util.js +64 -0
  54. package/cjs/utils/index.js +5 -1
  55. package/cjs/utils/query-helpers.util.js +60 -0
  56. package/cjs/utils/request.util.js +96 -0
  57. package/cjs/utils/string.util.js +63 -0
  58. package/classes/api-controller.class.d.ts +16 -8
  59. package/classes/api-service.class.d.ts +30 -25
  60. package/classes/handle-custome-db.d.ts +3 -0
  61. package/classes/index.d.ts +2 -2
  62. package/classes/winston.logger.class.d.ts +1 -0
  63. package/constants/index.d.ts +2 -1
  64. package/constants/message-keys.d.ts +45 -0
  65. package/constants/permissions.d.ts +306 -0
  66. package/decorators/api-response.decorator.d.ts +1 -1
  67. package/decorators/current-user.decorator.d.ts +1 -1
  68. package/decorators/index.d.ts +1 -0
  69. package/decorators/log-action.decorator.d.ts +8 -0
  70. package/decorators/require-permission.decorator.d.ts +2 -2
  71. package/dtos/delete.dto.d.ts +1 -0
  72. package/dtos/filter-and-pagination.dto.d.ts +0 -2
  73. package/dtos/get-by-ids.dto.d.ts +4 -0
  74. package/dtos/index.d.ts +1 -0
  75. package/dtos/response-payload.dto.d.ts +8 -20
  76. package/entities/index.d.ts +1 -0
  77. package/entities/raw-type.d.ts +1 -0
  78. package/enums/index.d.ts +3 -0
  79. package/enums/notification-type.enum.d.ts +6 -0
  80. package/enums/participant-status.enum.d.ts +6 -0
  81. package/enums/recurrence-type.enum.d.ts +7 -0
  82. package/exceptions/base-app.exception.d.ts +41 -0
  83. package/exceptions/index.d.ts +1 -0
  84. package/exceptions/permission.exception.d.ts +2 -2
  85. package/fesm/classes/api-controller.class.js +326 -50
  86. package/fesm/classes/api-service.class.js +274 -152
  87. package/fesm/classes/handle-custome-db.js +19 -0
  88. package/fesm/classes/index.js +3 -2
  89. package/fesm/classes/winston.logger.class.js +100 -68
  90. package/fesm/constants/index.js +4 -1
  91. package/fesm/constants/message-keys.js +49 -0
  92. package/fesm/constants/permissions.js +200 -0
  93. package/fesm/decorators/api-response.decorator.js +3 -21
  94. package/fesm/decorators/index.js +1 -0
  95. package/fesm/decorators/log-action.decorator.js +139 -0
  96. package/fesm/decorators/require-permission.decorator.js +17 -65
  97. package/fesm/dtos/delete.dto.js +12 -2
  98. package/fesm/dtos/filter-and-pagination.dto.js +26 -47
  99. package/fesm/dtos/get-by-ids.dto.js +55 -0
  100. package/fesm/dtos/identity-response.dto.js +4 -8
  101. package/fesm/dtos/index.js +1 -0
  102. package/fesm/dtos/pagination.dto.js +4 -8
  103. package/fesm/dtos/response-payload.dto.js +68 -103
  104. package/fesm/entities/identity.js +12 -6
  105. package/fesm/entities/index.js +1 -0
  106. package/fesm/entities/raw-type.js +1 -0
  107. package/fesm/entities/user-root.js +15 -15
  108. package/fesm/enums/index.js +3 -0
  109. package/fesm/enums/notification-type.enum.js +7 -0
  110. package/fesm/enums/participant-status.enum.js +7 -0
  111. package/fesm/enums/recurrence-type.enum.js +8 -0
  112. package/fesm/exceptions/base-app.exception.js +115 -0
  113. package/fesm/exceptions/index.js +1 -0
  114. package/fesm/exceptions/permission.exception.js +16 -18
  115. package/fesm/filters/global-exception.filter.js +269 -0
  116. package/fesm/filters/index.js +1 -0
  117. package/fesm/guards/jwt-auth.guard.js +5 -2
  118. package/fesm/guards/permission.guard.js +90 -150
  119. package/fesm/index.js +2 -0
  120. package/fesm/interceptors/idempotency.interceptor.js +2 -2
  121. package/fesm/interceptors/index.js +1 -4
  122. package/fesm/interceptors/set-user-field-on-body.interceptor.js +39 -0
  123. package/fesm/interceptors/slug.interceptor.js +31 -10
  124. package/fesm/interfaces/datasource.interface.js +1 -0
  125. package/fesm/interfaces/event-manager-adapter.interface.js +1 -0
  126. package/fesm/interfaces/index.js +4 -2
  127. package/fesm/interfaces/module-config.interface.js +5 -0
  128. package/fesm/interfaces/notification-adapter.interface.js +1 -0
  129. package/fesm/interfaces/permission.interface.js +1 -3
  130. package/fesm/middlewares/logger.middleware.js +133 -109
  131. package/fesm/modules/cache/cache.module.js +2 -2
  132. package/fesm/modules/datasource/index.js +0 -1
  133. package/fesm/modules/datasource/multi-tenant-datasource.service.js +61 -184
  134. package/fesm/modules/utils/utils.service.js +27 -206
  135. package/fesm/utils/date-time.util.js +70 -0
  136. package/fesm/utils/html-sanitizer.util.js +69 -0
  137. package/fesm/utils/index.js +5 -1
  138. package/fesm/utils/query-helpers.util.js +85 -0
  139. package/fesm/utils/request.util.js +81 -0
  140. package/fesm/utils/string.util.js +71 -0
  141. package/filters/global-exception.filter.d.ts +9 -0
  142. package/filters/index.d.ts +1 -0
  143. package/guards/permission.guard.d.ts +4 -6
  144. package/index.d.ts +2 -0
  145. package/interceptors/idempotency.interceptor.d.ts +1 -1
  146. package/interceptors/index.d.ts +1 -4
  147. package/interceptors/set-user-field-on-body.interceptor.d.ts +5 -0
  148. package/interceptors/slug.interceptor.d.ts +2 -1
  149. package/interfaces/api.interface.d.ts +4 -2
  150. package/interfaces/datasource.interface.d.ts +5 -0
  151. package/interfaces/event-manager-adapter.interface.d.ts +43 -0
  152. package/interfaces/identity.interface.d.ts +4 -4
  153. package/interfaces/index.d.ts +4 -2
  154. package/interfaces/logged-user-info.interface.d.ts +0 -2
  155. package/interfaces/module-config.interface.d.ts +6 -0
  156. package/interfaces/notification-adapter.interface.d.ts +21 -0
  157. package/interfaces/permission.interface.d.ts +13 -9
  158. package/middlewares/logger.middleware.d.ts +2 -2
  159. package/modules/datasource/index.d.ts +0 -1
  160. package/modules/datasource/multi-tenant-datasource.service.d.ts +5 -16
  161. package/modules/utils/utils.service.d.ts +3 -14
  162. package/package.json +21 -14
  163. package/utils/date-time.util.d.ts +8 -0
  164. package/utils/html-sanitizer.util.d.ts +2 -0
  165. package/utils/index.d.ts +5 -1
  166. package/utils/query-helpers.util.d.ts +16 -0
  167. package/utils/request.util.d.ts +6 -0
  168. package/utils/string.util.d.ts +2 -0
  169. package/cjs/classes/request-scoped-api.service.js +0 -61
  170. package/cjs/classes/winston-logger-adapter.class.js +0 -121
  171. package/cjs/interceptors/query-performance.interceptor.js +0 -66
  172. package/cjs/interceptors/set-create-by-on-body.interceptor.js +0 -40
  173. package/cjs/interceptors/set-delete-by-on-body.interceptor.js +0 -40
  174. package/cjs/interceptors/set-update-by-on-body.interceptor.js +0 -40
  175. package/cjs/interfaces/base-query.interface.js +0 -6
  176. package/cjs/interfaces/logger.interface.js +0 -7
  177. package/cjs/modules/datasource/datasource.module.js +0 -120
  178. package/cjs/utils/error-handler.util.js +0 -67
  179. package/classes/request-scoped-api.service.d.ts +0 -13
  180. package/classes/winston-logger-adapter.class.d.ts +0 -20
  181. package/fesm/classes/request-scoped-api.service.js +0 -51
  182. package/fesm/classes/winston-logger-adapter.class.js +0 -124
  183. package/fesm/interceptors/query-performance.interceptor.js +0 -56
  184. package/fesm/interceptors/set-create-by-on-body.interceptor.js +0 -30
  185. package/fesm/interceptors/set-delete-by-on-body.interceptor.js +0 -30
  186. package/fesm/interceptors/set-update-by-on-body.interceptor.js +0 -30
  187. package/fesm/interfaces/base-query.interface.js +0 -3
  188. package/fesm/interfaces/logger.interface.js +0 -4
  189. package/fesm/modules/datasource/datasource.module.js +0 -110
  190. package/fesm/utils/error-handler.util.js +0 -59
  191. package/interceptors/query-performance.interceptor.d.ts +0 -8
  192. package/interceptors/set-create-by-on-body.interceptor.d.ts +0 -5
  193. package/interceptors/set-delete-by-on-body.interceptor.d.ts +0 -5
  194. package/interceptors/set-update-by-on-body.interceptor.d.ts +0 -5
  195. package/interfaces/base-query.interface.d.ts +0 -7
  196. package/interfaces/logger.interface.d.ts +0 -7
  197. package/modules/datasource/datasource.module.d.ts +0 -18
  198. package/utils/error-handler.util.d.ts +0 -24
@@ -8,9 +8,14 @@ Object.defineProperty(exports, "ApiService", {
8
8
  return ApiService;
9
9
  }
10
10
  });
11
- const _errorhandlerutil = require("../utils/error-handler.util");
12
11
  const _common = require("@nestjs/common");
13
12
  const _typeorm = require("typeorm");
13
+ const _constants = require("../constants");
14
+ const _logactiondecorator = require("../decorators/log-action.decorator");
15
+ const _dtos = require("../dtos");
16
+ const _interfaces = require("../interfaces");
17
+ const _utilsservice = require("../modules/utils/utils.service");
18
+ const _hybridcacheclass = require("./hybrid-cache.class");
14
19
  function _define_property(obj, key, value) {
15
20
  if (key in obj) {
16
21
  Object.defineProperty(obj, key, {
@@ -24,127 +29,121 @@ function _define_property(obj, key, value) {
24
29
  }
25
30
  return obj;
26
31
  }
32
+ function _ts_decorate(decorators, target, key, desc) {
33
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
34
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
35
+ 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;
36
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
37
+ }
38
+ function _ts_metadata(k, v) {
39
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
40
+ }
27
41
  let ApiService = class ApiService {
42
+ resolveEntity() {
43
+ return this._entity;
44
+ }
45
+ getDataSourceProvider() {
46
+ return this._dataSourceProvider;
47
+ }
48
+ async ensureDataSourceRepository() {
49
+ if (!this.repositoryInitialized) {
50
+ const entity = this.resolveEntity();
51
+ const provider = this.getDataSourceProvider();
52
+ this.repository = await provider.getRepository(entity);
53
+ this.repositoryInitialized = true;
54
+ }
55
+ }
56
+ async resolveRepositories(entities) {
57
+ const provider = this.getDataSourceProvider();
58
+ const repositories = [];
59
+ for (const entity of entities){
60
+ repositories.push(await provider.getRepository(entity));
61
+ }
62
+ return repositories;
63
+ }
64
+ async getDataSourceForService() {
65
+ return this.getDataSourceProvider().getDataSource();
66
+ }
28
67
  async insert(dto, user) {
29
- await this.ensureRepositoryInitialized();
30
- const qr = this.repository.manager.connection.createQueryRunner();
31
- await qr.connect();
32
- await qr.startTransaction();
33
- try {
68
+ return this.executeInTransaction('insert', async (qr)=>{
34
69
  await this.beforeInsertOperation(dto, user, qr);
35
70
  const entities = await this.convertRequestDtoToEntity(dto, user);
36
71
  const saved = await qr.manager.save(this.repository.target, entities);
37
- await this.afterInsertOperation(saved, user, qr);
38
- await qr.commitTransaction();
39
- if (this.isCacheable) await Promise.all([
40
- this.clearCacheForAll(),
41
- this.clearCacheForId(Array.isArray(saved) ? saved : [
42
- saved
43
- ])
44
- ]);
45
- const first = Array.isArray(saved) ? saved[0] : saved;
46
- return this.convertEntityToResponseDto(first, false);
47
- } catch (error) {
48
- await qr.rollbackTransaction();
49
- this.handleError(error, 'insert');
50
- } finally{
51
- await qr.release();
52
- }
72
+ await this.afterInsertOperation(this.ensureArray(saved), dto, user, qr);
73
+ return {
74
+ saved,
75
+ returnFirst: true
76
+ };
77
+ });
53
78
  }
54
79
  async insertMany(dtos, user) {
55
- await this.ensureRepositoryInitialized();
56
- const qr = this.repository.manager.connection.createQueryRunner();
57
- await qr.connect();
58
- await qr.startTransaction();
59
- try {
80
+ return this.executeInTransaction('insertMany', async (qr)=>{
60
81
  await this.beforeInsertOperation(dtos, user, qr);
61
82
  const entities = await this.convertRequestDtoToEntity(dtos, user);
62
83
  const saved = await qr.manager.save(this.repository.target, entities);
63
- await this.afterInsertOperation(Array.isArray(saved) ? saved : [
64
- saved
65
- ], user, qr);
66
- await qr.commitTransaction();
67
- if (this.isCacheable) await Promise.all([
68
- this.clearCacheForAll(),
69
- this.clearCacheForId(Array.isArray(saved) ? saved : [
70
- saved
71
- ])
72
- ]);
73
- const list = (Array.isArray(saved) ? saved : [
74
- saved
75
- ]).map((e)=>this.convertEntityToResponseDto(e, false));
76
- return list;
77
- } catch (error) {
78
- await qr.rollbackTransaction();
79
- this.handleError(error, 'insertMany');
80
- } finally{
81
- await qr.release();
82
- }
84
+ await this.afterInsertOperation(this.ensureArray(saved), dtos, user, qr);
85
+ return {
86
+ saved,
87
+ returnFirst: false
88
+ };
89
+ });
83
90
  }
84
91
  async update(dto, user) {
85
- await this.ensureRepositoryInitialized();
86
- const qr = this.repository.manager.connection.createQueryRunner();
87
- await qr.connect();
88
- await qr.startTransaction();
89
- try {
92
+ return this.executeInTransaction('update', async (qr)=>{
90
93
  await this.beforeUpdateOperation(dto, user, qr);
91
94
  const entities = await this.convertRequestDtoToEntity(dto, user);
92
95
  const saved = await qr.manager.save(this.repository.target, entities);
93
- await this.afterUpdateOperation(saved, user, qr);
94
- await qr.commitTransaction();
95
- if (this.isCacheable) await Promise.all([
96
- this.clearCacheForAll(),
97
- this.clearCacheForId(Array.isArray(saved) ? saved : [
98
- saved
99
- ])
100
- ]);
101
- const first = Array.isArray(saved) ? saved[0] : saved;
102
- return this.convertEntityToResponseDto(first, false);
103
- } catch (error) {
104
- await qr.rollbackTransaction();
105
- this.handleError(error, 'update');
106
- } finally{
107
- await qr.release();
108
- }
96
+ await this.afterUpdateOperation(this.ensureArray(saved), dto, user, qr);
97
+ return {
98
+ saved,
99
+ returnFirst: true
100
+ };
101
+ });
109
102
  }
110
103
  async updateMany(dtos, user) {
111
- await this.ensureRepositoryInitialized();
112
- const qr = this.repository.manager.connection.createQueryRunner();
113
- await qr.connect();
114
- await qr.startTransaction();
115
- try {
104
+ return this.executeInTransaction('updateMany', async (qr)=>{
116
105
  await this.beforeUpdateOperation(dtos, user, qr);
117
106
  const entities = await this.convertRequestDtoToEntity(dtos, user);
118
107
  const saved = await qr.manager.save(this.repository.target, entities);
119
- await this.afterUpdateOperation(Array.isArray(saved) ? saved : [
120
- saved
121
- ], user, qr);
122
- await qr.commitTransaction();
123
- if (this.isCacheable) await Promise.all([
124
- this.clearCacheForAll(),
125
- this.clearCacheForId(Array.isArray(saved) ? saved : [
126
- saved
127
- ])
128
- ]);
129
- const list = (Array.isArray(saved) ? saved : [
130
- saved
131
- ]).map((e)=>this.convertEntityToResponseDto(e, false));
132
- return list;
133
- } catch (error) {
134
- await qr.rollbackTransaction();
135
- this.handleError(error, 'updateMany');
136
- } finally{
137
- await qr.release();
138
- }
108
+ await this.afterUpdateOperation(this.ensureArray(saved), dtos, user, qr);
109
+ return {
110
+ saved,
111
+ returnFirst: false
112
+ };
113
+ });
114
+ }
115
+ async bulkUpsert(toInsert, toUpdate, user) {
116
+ return this.executeInTransaction('bulkUpsert', async (qr)=>{
117
+ const allResults = [];
118
+ if (toInsert.length > 0) {
119
+ await this.beforeInsertOperation(toInsert, user, qr);
120
+ const insertedEntities = await this.convertRequestDtoToEntity(toInsert, user);
121
+ const insertedSaved = await qr.manager.save(this.repository.target, insertedEntities);
122
+ await this.afterInsertOperation(this.ensureArray(insertedSaved), toInsert, user, qr);
123
+ allResults.push(...this.ensureArray(insertedSaved));
124
+ }
125
+ if (toUpdate.length > 0) {
126
+ await this.beforeUpdateOperation(toUpdate, user, qr);
127
+ const updatedEntities = await this.convertRequestDtoToEntity(toUpdate, user);
128
+ const updatedSaved = await qr.manager.save(this.repository.target, updatedEntities);
129
+ await this.afterUpdateOperation(this.ensureArray(updatedSaved), toUpdate, user, qr);
130
+ allResults.push(...this.ensureArray(updatedSaved));
131
+ }
132
+ return {
133
+ saved: allResults,
134
+ returnFirst: false
135
+ };
136
+ });
139
137
  }
140
- async findByIds(ids, user) {
141
- await this.ensureRepositoryInitialized();
138
+ async findByIds(ids, user, select) {
139
+ await this.ensureDataSourceRepository();
142
140
  try {
143
141
  const query = this.repository.createQueryBuilder(this.entityName);
144
142
  query.where({
145
143
  id: (0, _typeorm.In)(ids)
146
144
  });
147
- const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user);
145
+ const selectArray = typeof select === 'string' ? select.split(',').map((s)=>s.trim()) : select;
146
+ const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user, selectArray);
148
147
  let output;
149
148
  if (isRaw) {
150
149
  output = await finalQuery.getRawMany();
@@ -152,7 +151,10 @@ let ApiService = class ApiService {
152
151
  output = await finalQuery.getMany();
153
152
  }
154
153
  const result = this.convertEntityListToResponseListDto(output, isRaw);
155
- if (!result || !result.length) throw new _common.NotFoundException('No Data Found');
154
+ if (!result || !result.length) throw new _common.NotFoundException({
155
+ message: 'No Data Found',
156
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
157
+ });
156
158
  return result;
157
159
  } catch (error) {
158
160
  if (error instanceof _common.NotFoundException) {
@@ -162,7 +164,7 @@ let ApiService = class ApiService {
162
164
  }
163
165
  }
164
166
  async findById(id, user, select) {
165
- await this.ensureRepositoryInitialized();
167
+ await this.ensureDataSourceRepository();
166
168
  try {
167
169
  const query = this.repository.createQueryBuilder(this.entityName);
168
170
  query.where({
@@ -176,15 +178,17 @@ let ApiService = class ApiService {
176
178
  result = await this.cacheManager.get(cacheKey);
177
179
  }
178
180
  if (!result) {
179
- let output;
180
181
  if (isRaw) {
181
- output = await finalQuery.getRawMany();
182
- const convertResult = this.convertEntityListToResponseListDto(output, isRaw);
182
+ const rawOutput = await finalQuery.getRawMany();
183
+ const convertResult = this.convertEntityListToResponseListDto(rawOutput, isRaw);
183
184
  if (convertResult.length) result = convertResult[0];
184
185
  } else {
185
- output = await finalQuery.getOne();
186
- if (!output) throw new _common.NotFoundException('No Data Found');
187
- result = this.convertEntityToResponseDto(output, false);
186
+ const singleOutput = await finalQuery.getOne();
187
+ if (!singleOutput) throw new _common.NotFoundException({
188
+ message: 'No Data Found',
189
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
190
+ });
191
+ result = this.convertEntityToResponseDto(singleOutput, false);
188
192
  }
189
193
  if (this.isCacheable) {
190
194
  await this.cacheManager.set(cacheKey, result);
@@ -200,43 +204,34 @@ let ApiService = class ApiService {
200
204
  }
201
205
  }
202
206
  async getAll(search, filterAndPaginationDto, user) {
203
- await this.ensureRepositoryInitialized();
207
+ await this.ensureDataSourceRepository();
204
208
  try {
205
209
  let data;
206
210
  let total;
207
211
  let isRaw = false;
208
212
  let query = this.repository.createQueryBuilder(this.entityName);
209
- // Apply filters
210
213
  if (filterAndPaginationDto.filter) {
211
214
  const { query: filterQuery, isRaw: filterIsRaw } = await this.getFilterQuery(query, filterAndPaginationDto.filter, user);
212
215
  query = filterQuery;
213
216
  isRaw = isRaw || filterIsRaw;
214
217
  }
215
- // Apply search
216
218
  if (search) {
217
219
  const { query: searchQuery, isRaw: searchIsRaw } = await this.getGlobalSearchQuery(query, search, user);
218
220
  query = searchQuery;
219
221
  isRaw = isRaw || searchIsRaw;
220
222
  }
221
- // Apply select
222
- if (filterAndPaginationDto.select) {
223
- const { query: selectQuery, isRaw: selectIsRaw } = await this.getSelectQuery(query, user, filterAndPaginationDto.select);
224
- query = selectQuery;
225
- isRaw = isRaw || selectIsRaw;
226
- }
227
- // Apply sort
223
+ const { query: selectQuery, isRaw: selectIsRaw } = await this.getSelectQuery(query, user, filterAndPaginationDto.select);
224
+ query = selectQuery;
225
+ isRaw = isRaw || selectIsRaw;
228
226
  if (filterAndPaginationDto.sort) {
229
227
  const { query: sortQuery, isRaw: sortIsRaw } = await this.getSortQuery(query, filterAndPaginationDto.sort, user);
230
228
  query = sortQuery;
231
229
  isRaw = isRaw || sortIsRaw;
232
230
  }
233
- // Include soft-deleted if requested
234
231
  if (filterAndPaginationDto.withDeleted) query.withDeleted();
235
- // Extra manipulation
236
232
  const { query: extraQuery, isRaw: extraIsRaw } = await this.getExtraManipulateQuery(query, filterAndPaginationDto, user);
237
233
  query = extraQuery;
238
234
  isRaw = isRaw || extraIsRaw;
239
- // Pagination
240
235
  if (filterAndPaginationDto.pagination) {
241
236
  const offset = filterAndPaginationDto.pagination.currentPage * filterAndPaginationDto.pagination.pageSize;
242
237
  const limit = filterAndPaginationDto.pagination.pageSize;
@@ -246,7 +241,6 @@ let ApiService = class ApiService {
246
241
  query.skip(offset).take(limit);
247
242
  }
248
243
  }
249
- // Generate cache key
250
244
  let cacheKey = '';
251
245
  if (this.isCacheable) {
252
246
  cacheKey = this.utilsService.getCacheKey(this.entityName, {
@@ -260,8 +254,9 @@ let ApiService = class ApiService {
260
254
  }
261
255
  }
262
256
  if (isRaw) {
263
- // Handle raw query count manually
264
- const rawSubQuery = query.clone().offset(undefined).limit(undefined).distinct(true);
257
+ const rawSubQuery = query.clone().offset(undefined).limit(undefined);
258
+ rawSubQuery.expressionMap.orderBys = {};
259
+ rawSubQuery.distinct(true);
265
260
  const countSql = `
266
261
  SELECT COUNT(*) as count
267
262
  FROM (
@@ -272,10 +267,20 @@ let ApiService = class ApiService {
272
267
  `;
273
268
  const parameters = rawSubQuery.getParameters();
274
269
  const orderedValues = [];
270
+ const isPostgres = this.repository.manager.connection.options.type === 'postgres';
271
+ let paramIndex = 0;
275
272
  const convertedQuery = countSql.replace(/:(\w+)/g, (_, key)=>{
276
- if (!(key in parameters)) throw new Error(`Missing parameter value for: ${key}`);
273
+ if (!(key in parameters)) {
274
+ throw new _common.InternalServerErrorException({
275
+ message: `Missing parameter value for: ${key}`,
276
+ messageKey: _constants.SYSTEM_MESSAGES.MISSING_PARAMETER,
277
+ messageVariables: {
278
+ key
279
+ }
280
+ });
281
+ }
277
282
  orderedValues.push(parameters[key]);
278
- return '?';
283
+ return isPostgres ? `$${++paramIndex}` : '?';
279
284
  });
280
285
  const result = await this.repository.query(convertedQuery, orderedValues);
281
286
  total = Number(result[0]?.count || 0);
@@ -298,7 +303,7 @@ let ApiService = class ApiService {
298
303
  }
299
304
  }
300
305
  async delete(option, user) {
301
- await this.ensureRepositoryInitialized();
306
+ await this.ensureDataSourceRepository();
302
307
  const queryRunner = this.repository.manager.connection.createQueryRunner();
303
308
  await queryRunner.connect();
304
309
  await queryRunner.startTransaction();
@@ -324,13 +329,12 @@ let ApiService = class ApiService {
324
329
  id
325
330
  };
326
331
  });
327
- await this.afterDeleteOperation(ids, user, queryRunner);
332
+ await this.afterDeleteOperation(ids, option, user, queryRunner);
328
333
  await queryRunner.commitTransaction();
329
334
  await Promise.all([
330
335
  this.clearCacheForAll(),
331
336
  this.clearCacheForId(ids)
332
337
  ]);
333
- // return null per IService contract
334
338
  return null;
335
339
  } catch (error) {
336
340
  await queryRunner.rollbackTransaction();
@@ -339,29 +343,58 @@ let ApiService = class ApiService {
339
343
  await queryRunner.release();
340
344
  }
341
345
  }
342
- // Caching
343
346
  async clearCacheForAll() {
344
347
  await this.utilsService.clearCache(this.entityName, this.cacheManager);
345
348
  }
346
349
  async clearCacheForId(entities) {
347
350
  await Promise.all(entities.map((item)=>this.utilsService.clearCache(this.entityName, this.cacheManager, item.id)));
348
351
  }
349
- /**
350
- * Helper method to handle errors with proper logging and type safety
351
- */ handleError(error, operation) {
352
- _errorhandlerutil.ErrorHandler.logError(this.logger, error, operation, {
353
- entity: this.entityName
352
+ handleError(error, _operation) {
353
+ if (error instanceof Error) {
354
+ throw error;
355
+ }
356
+ throw new _common.InternalServerErrorException({
357
+ message: typeof error === 'string' ? error : 'Unknown error',
358
+ messageKey: _constants.ERROR_MESSAGES.INTERNAL
354
359
  });
355
- _errorhandlerutil.ErrorHandler.rethrowError(error);
356
360
  }
357
- // Hooks (override in child classes)
358
- async ensureRepositoryInitialized() {}
361
+ ensureArray(value) {
362
+ return Array.isArray(value) ? value : [
363
+ value
364
+ ];
365
+ }
366
+ async executeInTransaction(operation, fn) {
367
+ await this.ensureDataSourceRepository();
368
+ const qr = this.repository.manager.connection.createQueryRunner();
369
+ await qr.connect();
370
+ await qr.startTransaction();
371
+ try {
372
+ const { saved, returnFirst } = await fn(qr);
373
+ await qr.commitTransaction();
374
+ const savedArray = this.ensureArray(saved);
375
+ if (this.isCacheable) {
376
+ await Promise.all([
377
+ this.clearCacheForAll(),
378
+ this.clearCacheForId(savedArray)
379
+ ]);
380
+ }
381
+ if (returnFirst) {
382
+ return this.convertEntityToResponseDto(savedArray[0], false);
383
+ }
384
+ return savedArray.map((e)=>this.convertEntityToResponseDto(e, false));
385
+ } catch (error) {
386
+ await qr.rollbackTransaction();
387
+ this.handleError(error, operation);
388
+ } finally{
389
+ await qr.release();
390
+ }
391
+ }
359
392
  async beforeInsertOperation(_dto, _user, _queryRunner) {}
360
- async afterInsertOperation(_entity, _user, _queryRunner) {}
393
+ async afterInsertOperation(_entity, _dto, _user, _queryRunner) {}
361
394
  async beforeUpdateOperation(_dto, _user, _queryRunner) {}
362
- async afterUpdateOperation(_entity, _user, _queryRunner) {}
395
+ async afterUpdateOperation(_entity, _dto, _user, _queryRunner) {}
363
396
  async beforeDeleteOperation(_dto, _user, _queryRunner) {}
364
- async afterDeleteOperation(_entity, _user, _queryRunner) {}
397
+ async afterDeleteOperation(_entity, _dto, _user, _queryRunner) {}
365
398
  async getFilterQuery(query, filter, _user) {
366
399
  Object.entries(filter).forEach(([key, value])=>{
367
400
  query.andWhere(`${this.entityName}.${key} = :value`, {
@@ -404,7 +437,6 @@ let ApiService = class ApiService {
404
437
  isRaw: false
405
438
  };
406
439
  }
407
- // DTO conversion
408
440
  async convertRequestDtoToEntity(dto, user) {
409
441
  return Array.isArray(dto) ? await this.convertArrayDtoToEntities(dto, user) : [
410
442
  await this.convertSingleDtoToEntity(dto, user)
@@ -418,7 +450,10 @@ let ApiService = class ApiService {
418
450
  id: d.id
419
451
  }
420
452
  });
421
- if (!existing) throw new _common.NotFoundException('No such entity data found for update! Please, Try Again.');
453
+ if (!existing) throw new _common.NotFoundException({
454
+ message: 'No such entity data found for update! Please, Try Again.',
455
+ messageKey: _constants.ERROR_MESSAGES.NOT_FOUND
456
+ });
422
457
  return Object.assign(existing, d);
423
458
  }
424
459
  delete d.id;
@@ -431,26 +466,113 @@ let ApiService = class ApiService {
431
466
  return Object.assign({}, entity);
432
467
  }
433
468
  convertEntityListToResponseListDto(entities, _isRaw) {
434
- return entities.map((entity)=>Object.assign({}, entity));
469
+ return entities.map((entity)=>this.convertEntityToResponseDto(entity, _isRaw));
435
470
  }
436
471
  async getEntityClass() {
437
- return await this.repository.create();
472
+ return this.repository.create();
438
473
  }
439
- constructor(entityName, repository, cacheManager, utilsService, loggerName, isCacheable = false){
474
+ constructor(entityName, cacheManager, utilsService, _loggerName, isCacheable = false, moduleName, entity, dataSourceProvider){
440
475
  _define_property(this, "entityName", void 0);
441
- _define_property(this, "repository", void 0);
442
476
  _define_property(this, "cacheManager", void 0);
443
477
  _define_property(this, "utilsService", void 0);
444
- _define_property(this, "loggerName", void 0);
478
+ _define_property(this, "_loggerName", void 0);
445
479
  _define_property(this, "isCacheable", void 0);
446
- _define_property(this, "logger", void 0);
480
+ _define_property(this, "moduleName", void 0);
481
+ _define_property(this, "repository", void 0);
482
+ _define_property(this, "repositoryInitialized", void 0);
483
+ _define_property(this, "_entity", void 0);
484
+ _define_property(this, "_dataSourceProvider", void 0);
447
485
  this.entityName = entityName;
448
- this.repository = repository;
449
486
  this.cacheManager = cacheManager;
450
487
  this.utilsService = utilsService;
451
- this.loggerName = loggerName;
488
+ this._loggerName = _loggerName;
452
489
  this.isCacheable = isCacheable;
453
- this.logger = new _common.Logger('ApiService');
454
- this.logger = new _common.Logger(loggerName);
490
+ this.moduleName = moduleName;
491
+ this.repositoryInitialized = false;
492
+ this._entity = entity;
493
+ this._dataSourceProvider = dataSourceProvider;
455
494
  }
456
495
  };
496
+ _ts_decorate([
497
+ (0, _logactiondecorator.LogAction)({
498
+ action: 'create'
499
+ }),
500
+ _ts_metadata("design:type", Function),
501
+ _ts_metadata("design:paramtypes", [
502
+ typeof CreateDtoT === "undefined" ? Object : CreateDtoT,
503
+ Object
504
+ ]),
505
+ _ts_metadata("design:returntype", Promise)
506
+ ], ApiService.prototype, "insert", null);
507
+ _ts_decorate([
508
+ (0, _logactiondecorator.LogAction)({
509
+ action: 'createMany'
510
+ }),
511
+ _ts_metadata("design:type", Function),
512
+ _ts_metadata("design:paramtypes", [
513
+ typeof Array === "undefined" ? Object : Array,
514
+ Object
515
+ ]),
516
+ _ts_metadata("design:returntype", Promise)
517
+ ], ApiService.prototype, "insertMany", null);
518
+ _ts_decorate([
519
+ (0, _logactiondecorator.LogAction)({
520
+ action: 'update'
521
+ }),
522
+ _ts_metadata("design:type", Function),
523
+ _ts_metadata("design:paramtypes", [
524
+ typeof UpdateDtoT === "undefined" ? Object : UpdateDtoT,
525
+ Object
526
+ ]),
527
+ _ts_metadata("design:returntype", Promise)
528
+ ], ApiService.prototype, "update", null);
529
+ _ts_decorate([
530
+ (0, _logactiondecorator.LogAction)({
531
+ action: 'updateMany'
532
+ }),
533
+ _ts_metadata("design:type", Function),
534
+ _ts_metadata("design:paramtypes", [
535
+ Array,
536
+ Object
537
+ ]),
538
+ _ts_metadata("design:returntype", Promise)
539
+ ], ApiService.prototype, "updateMany", null);
540
+ _ts_decorate([
541
+ (0, _logactiondecorator.LogAction)({
542
+ action: 'bulkUpsert'
543
+ }),
544
+ _ts_metadata("design:type", Function),
545
+ _ts_metadata("design:paramtypes", [
546
+ Array,
547
+ Array,
548
+ Object
549
+ ]),
550
+ _ts_metadata("design:returntype", Promise)
551
+ ], ApiService.prototype, "bulkUpsert", null);
552
+ _ts_decorate([
553
+ (0, _logactiondecorator.LogAction)({
554
+ action: 'delete'
555
+ }),
556
+ _ts_metadata("design:type", Function),
557
+ _ts_metadata("design:paramtypes", [
558
+ typeof _dtos.DeleteDto === "undefined" ? Object : _dtos.DeleteDto,
559
+ Object
560
+ ]),
561
+ _ts_metadata("design:returntype", Promise)
562
+ ], ApiService.prototype, "delete", null);
563
+ ApiService = _ts_decorate([
564
+ (0, _common.Injectable)({
565
+ scope: _common.Scope.REQUEST
566
+ }),
567
+ _ts_metadata("design:type", Function),
568
+ _ts_metadata("design:paramtypes", [
569
+ String,
570
+ typeof _hybridcacheclass.HybridCache === "undefined" ? Object : _hybridcacheclass.HybridCache,
571
+ typeof _utilsservice.UtilsService === "undefined" ? Object : _utilsservice.UtilsService,
572
+ String,
573
+ Boolean,
574
+ String,
575
+ typeof _typeorm.EntityTarget === "undefined" ? Object : _typeorm.EntityTarget,
576
+ typeof _interfaces.IDataSourceProvider === "undefined" ? Object : _interfaces.IDataSourceProvider
577
+ ])
578
+ ], ApiService);
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get buildQuery () {
13
+ return buildQuery;
14
+ },
15
+ get getCastIntType () {
16
+ return getCastIntType;
17
+ },
18
+ get getJsonColumnType () {
19
+ return getJsonColumnType;
20
+ }
21
+ });
22
+ const _nestjscore = require("@flusys/nestjs-core");
23
+ function getJsonColumnType() {
24
+ const driver = _nestjscore.envConfig.getTypeOrmConfig().type;
25
+ if (driver === 'postgres') return 'jsonb';
26
+ if (driver === 'mysql') return 'json';
27
+ return 'simple-json';
28
+ }
29
+ function getCastIntType() {
30
+ const driver = _nestjscore.envConfig.getTypeOrmConfig().type;
31
+ return driver === 'postgres' ? 'INTEGER' : 'UNSIGNED';
32
+ }
33
+ function buildQuery(sql, dbType) {
34
+ if (dbType !== 'postgres') return sql;
35
+ let index = 0;
36
+ return sql.replace(/\?/g, ()=>`$${++index}`);
37
+ }
@@ -4,10 +4,10 @@ Object.defineProperty(exports, "__esModule", {
4
4
  });
5
5
  _export_star(require("./api-controller.class"), exports);
6
6
  _export_star(require("./api-service.class"), exports);
7
- _export_star(require("./request-scoped-api.service"), exports);
7
+ _export_star(require("./handle-custome-db"), exports);
8
8
  _export_star(require("./hybrid-cache.class"), exports);
9
- _export_star(require("./winston-logger-adapter.class"), exports);
10
9
  _export_star(require("./winston.logger.class"), exports);
10
+ _export_star(require("../constants/permissions"), exports);
11
11
  function _export_star(from, to) {
12
12
  Object.keys(from).forEach(function(k) {
13
13
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {