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