@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
|
@@ -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
|
|
76
|
-
if (security.
|
|
77
|
-
decorators.push((0, _decorators.
|
|
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 === '
|
|
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 = (
|
|
172
|
+
const data = toDto(responseDtoClass, entity);
|
|
125
173
|
return {
|
|
126
174
|
success: true,
|
|
127
|
-
message:
|
|
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)=>(
|
|
192
|
+
const data = entities.map((item)=>toDto(responseDtoClass, item));
|
|
134
193
|
return {
|
|
135
194
|
success: true,
|
|
136
|
-
message: `${data.length}
|
|
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 = (
|
|
220
|
+
const data = toDto(responseDtoClass, entity);
|
|
148
221
|
return {
|
|
149
222
|
success: true,
|
|
150
|
-
message:
|
|
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 = (
|
|
267
|
+
const data = toDto(responseDtoClass, entity);
|
|
157
268
|
return {
|
|
158
269
|
success: true,
|
|
159
|
-
message:
|
|
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 = (
|
|
287
|
+
const data = entities.map((item)=>toDto(responseDtoClass, item));
|
|
166
288
|
return {
|
|
167
289
|
success: true,
|
|
168
|
-
message: `${data.length}
|
|
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 = (
|
|
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:
|
|
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' ? '
|
|
414
|
+
const action = deleteDto.type === 'restore' ? 'restore' : 'delete';
|
|
201
415
|
return {
|
|
202
416
|
success: true,
|
|
203
|
-
message: `${count}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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),
|