@flusys/nestjs-shared 8.1.4 → 9.1.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 +48 -2
- package/classes/api-service.class.d.ts +3 -0
- package/constants/permissions.d.ts +46 -0
- package/exceptions/base-app.exception.d.ts +3 -2
- package/fesm/{509.js → 183.js} +43 -37
- package/fesm/470.js +228 -105
- package/fesm/667.js +28 -10
- package/fesm/{67.js → 681.js} +97 -19
- package/fesm/{720.js → 948.js} +60 -7
- package/fesm/chunks/123.js +9 -10
- package/fesm/chunks/37.js +7 -8
- package/fesm/classes/index.js +10 -4
- package/fesm/constants/index.js +53 -1
- package/fesm/decorators/index.js +4 -4
- package/fesm/dtos/index.js +2 -2
- package/fesm/guards/index.js +48 -426
- package/fesm/index.js +422 -341
- package/fesm/interceptors/index.js +62 -23
- package/fesm/interfaces/index.js +16 -3
- package/fesm/middlewares/index.js +5 -3
- package/fesm/modules/index.js +6 -414
- package/fesm/pipes/index.js +196 -0
- package/fesm/utils/index.js +125 -10
- package/index.d.ts +1 -0
- package/interfaces/datasource.interface.d.ts +2 -0
- package/interfaces/index.d.ts +3 -0
- package/interfaces/message-ref.interface.d.ts +4 -0
- package/interfaces/permission-action-registry.interface.d.ts +12 -0
- package/interfaces/permission-resolver.interface.d.ts +9 -0
- package/middlewares/logger.middleware.d.ts +4 -0
- package/modules/shared-permission-cache/shared-permission-cache.service.d.ts +5 -0
- package/package.json +8 -2
- package/pipes/dto-body-validation.pipe.d.ts +18 -0
- package/pipes/index.d.ts +1 -0
- package/utils/cache-tenant.util.d.ts +2 -0
- package/utils/index.d.ts +3 -0
- package/utils/message-ref.util.d.ts +2 -0
- package/utils/permission-match.util.d.ts +1 -0
- package/utils/query-helpers.util.d.ts +2 -1
package/fesm/470.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import * as __rspack_external_crypto from "crypto";
|
|
2
1
|
import * as __rspack_external__nestjs_passport_18907953 from "@nestjs/passport";
|
|
3
2
|
import * as __rspack_external_rxjs from "rxjs";
|
|
4
3
|
import * as __rspack_external_rxjs_operators_2eaa0997 from "rxjs/operators";
|
|
@@ -49,10 +48,14 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
49
48
|
XI: () => (/* reexport */ disabled_event_bus_class/* .DisabledEventBus */.X),
|
|
50
49
|
V0: () => (/* reexport */ permissions/* .EMAIL_CONFIG_PERMISSIONS */.V0),
|
|
51
50
|
z$: () => (/* reexport */ permissions/* .EMAIL_TEMPLATE_PERMISSIONS */.z$),
|
|
51
|
+
G0: () => (/* reexport */ permissions/* .ENTITY_BUILDER_ALL_DYNAMIC */.G0),
|
|
52
|
+
DP: () => (/* reexport */ permissions/* .ENTITY_DEFINITION_PERMISSIONS */.DP),
|
|
52
53
|
Ub: () => (/* reexport */ permissions/* .EVENT_PERMISSIONS */.Ub),
|
|
53
54
|
qS: () => (/* reexport */ event_bus_registry/* .EventBusRegistry */.q),
|
|
54
55
|
Pm: () => (/* reexport */ event_transport_registry/* .EventTransportRegistry */.P),
|
|
56
|
+
kA: () => (/* reexport */ permissions/* .FIELD_DEFINITION_PERMISSIONS */.kA),
|
|
55
57
|
S6: () => (/* reexport */ permissions/* .FILE_PERMISSIONS */.S6),
|
|
58
|
+
kd: () => (/* reexport */ permissions/* .FLOW_DEFINITION_PERMISSIONS */.kd),
|
|
56
59
|
wM: () => (/* reexport */ permissions/* .FOLDER_PERMISSIONS */.wM),
|
|
57
60
|
Wc: () => (/* reexport */ permissions/* .FORM_PERMISSIONS */.Wc),
|
|
58
61
|
GT: () => (/* reexport */ permissions/* .FORM_RESULT_PERMISSIONS */.GT),
|
|
@@ -81,6 +84,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
81
84
|
Zq: () => (/* reexport */ handle_custome_db/* .buildQuery */.Zq),
|
|
82
85
|
RD: () => (/* reexport */ createApiController),
|
|
83
86
|
Xv: () => (/* reexport */ winston_logger_class/* .createModuleLogger */.X),
|
|
87
|
+
aT: () => (/* reexport */ permissions/* .dynamicEntityPermission */.aT),
|
|
88
|
+
GH: () => (/* reexport */ permissions/* .dynamicEntityPermissionParent */.GH),
|
|
84
89
|
Tj: () => (/* reexport */ handle_custome_db/* .getCastIntType */.Tj),
|
|
85
90
|
pf: () => (/* reexport */ handle_custome_db/* .getJsonColumnType */.pf),
|
|
86
91
|
KJ: () => (/* reexport */ winston_logger_class/* .instance */.K),
|
|
@@ -99,14 +104,16 @@ var message_keys = __webpack_require__(389);
|
|
|
99
104
|
var src_decorators = __webpack_require__(523);
|
|
100
105
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/decorators/api-response.decorator.ts
|
|
101
106
|
var api_response_decorator = __webpack_require__(997);
|
|
102
|
-
// EXTERNAL MODULE: ./projects/nestjs-shared/src/dtos/index.ts +
|
|
103
|
-
var src_dtos = __webpack_require__(
|
|
107
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/dtos/index.ts + 6 modules
|
|
108
|
+
var src_dtos = __webpack_require__(746);
|
|
104
109
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/exceptions/index.ts
|
|
105
110
|
var exceptions = __webpack_require__(448);
|
|
106
111
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/guards/index.ts + 4 modules
|
|
107
112
|
var guards = __webpack_require__(510);
|
|
108
113
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/interceptors/index.ts + 7 modules
|
|
109
114
|
var interceptors = __webpack_require__(863);
|
|
115
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/pipes/index.ts + 1 modules
|
|
116
|
+
var pipes = __webpack_require__(928);
|
|
110
117
|
;// CONCATENATED MODULE: ./projects/nestjs-shared/src/classes/api-controller.class.ts
|
|
111
118
|
function _ts_decorate(decorators, target, key, desc) {
|
|
112
119
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -141,6 +148,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
141
148
|
|
|
142
149
|
|
|
143
150
|
|
|
151
|
+
|
|
144
152
|
/**
|
|
145
153
|
* Helper to normalize security config
|
|
146
154
|
*/ function normalizeSecurity(config) {
|
|
@@ -212,6 +220,22 @@ function _ts_param(paramIndex, decorator) {
|
|
|
212
220
|
}
|
|
213
221
|
// Entity name for message keys (defaults to 'item')
|
|
214
222
|
const entityName = options.entityName ?? 'item';
|
|
223
|
+
const insertBodyPipe = pipes/* .DtoBodyValidationPipe["for"] */.zT["for"](createDtoClass, [
|
|
224
|
+
'createdById'
|
|
225
|
+
]);
|
|
226
|
+
const insertManyBodyPipe = pipes/* .DtoBodyValidationPipe["for"] */.zT["for"](createDtoClass, [
|
|
227
|
+
'createdById'
|
|
228
|
+
], true);
|
|
229
|
+
const updateBodyPipe = pipes/* .DtoBodyValidationPipe["for"] */.zT["for"](updateDtoClass, [
|
|
230
|
+
'updatedById'
|
|
231
|
+
]);
|
|
232
|
+
const updateManyBodyPipe = pipes/* .DtoBodyValidationPipe["for"] */.zT["for"](updateDtoClass, [
|
|
233
|
+
'updatedById'
|
|
234
|
+
], true);
|
|
235
|
+
const bulkUpsertBodyPipe = new pipes/* .DtoBodyValidationPipe */.zT((item)=>item.id ? updateDtoClass : createDtoClass, [
|
|
236
|
+
'createdById',
|
|
237
|
+
'updatedById'
|
|
238
|
+
], true);
|
|
215
239
|
// Determine if security is global (applies to all) or per-endpoint
|
|
216
240
|
const securityConfig = options.security;
|
|
217
241
|
const endpointKeys = [
|
|
@@ -542,7 +566,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
542
566
|
type: createDtoClass
|
|
543
567
|
}),
|
|
544
568
|
(0,common_.UseInterceptors)(interceptors/* .IdempotencyInterceptor */.Bw, interceptors/* .SetCreatedByOnBody */.VS, interceptors/* .Slug */.Mw),
|
|
545
|
-
_ts_param(0, (0,common_.Body)()),
|
|
569
|
+
_ts_param(0, (0,common_.Body)(insertBodyPipe)),
|
|
546
570
|
_ts_param(1, (0,src_decorators/* .CurrentUser */.NO)()),
|
|
547
571
|
_ts_metadata("design:type", Function),
|
|
548
572
|
_ts_metadata("design:paramtypes", [
|
|
@@ -571,7 +595,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
571
595
|
isArray: true
|
|
572
596
|
}),
|
|
573
597
|
(0,common_.UseInterceptors)(interceptors/* .IdempotencyInterceptor */.Bw, interceptors/* .SetCreatedByOnBody */.VS, interceptors/* .Slug */.Mw),
|
|
574
|
-
_ts_param(0, (0,common_.Body)()),
|
|
598
|
+
_ts_param(0, (0,common_.Body)(insertManyBodyPipe)),
|
|
575
599
|
_ts_param(1, (0,src_decorators/* .CurrentUser */.NO)()),
|
|
576
600
|
_ts_metadata("design:type", Function),
|
|
577
601
|
_ts_metadata("design:paramtypes", [
|
|
@@ -646,7 +670,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
646
670
|
type: updateDtoClass
|
|
647
671
|
}),
|
|
648
672
|
(0,common_.UseInterceptors)(interceptors/* .SetUpdateByOnBody */._x, interceptors/* .Slug */.Mw),
|
|
649
|
-
_ts_param(0, (0,common_.Body)()),
|
|
673
|
+
_ts_param(0, (0,common_.Body)(updateBodyPipe)),
|
|
650
674
|
_ts_param(1, (0,src_decorators/* .CurrentUser */.NO)()),
|
|
651
675
|
_ts_metadata("design:type", Function),
|
|
652
676
|
_ts_metadata("design:paramtypes", [
|
|
@@ -670,7 +694,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
670
694
|
isArray: true
|
|
671
695
|
}),
|
|
672
696
|
(0,common_.UseInterceptors)(interceptors/* .SetUpdateByOnBody */._x, interceptors/* .Slug */.Mw),
|
|
673
|
-
_ts_param(0, (0,common_.Body)()),
|
|
697
|
+
_ts_param(0, (0,common_.Body)(updateManyBodyPipe)),
|
|
674
698
|
_ts_param(1, (0,src_decorators/* .CurrentUser */.NO)()),
|
|
675
699
|
_ts_metadata("design:type", Function),
|
|
676
700
|
_ts_metadata("design:paramtypes", [
|
|
@@ -694,7 +718,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
694
718
|
isArray: true
|
|
695
719
|
}),
|
|
696
720
|
(0,common_.UseInterceptors)(interceptors/* .SetCreatedByOnBody */.VS, interceptors/* .SetUpdateByOnBody */._x, interceptors/* .Slug */.Mw),
|
|
697
|
-
_ts_param(0, (0,common_.Body)()),
|
|
721
|
+
_ts_param(0, (0,common_.Body)(bulkUpsertBodyPipe)),
|
|
698
722
|
_ts_param(1, (0,src_decorators/* .CurrentUser */.NO)()),
|
|
699
723
|
_ts_metadata("design:type", Function),
|
|
700
724
|
_ts_metadata("design:paramtypes", [
|
|
@@ -824,14 +848,18 @@ function _ts_param(paramIndex, decorator) {
|
|
|
824
848
|
|
|
825
849
|
// EXTERNAL MODULE: external "typeorm"
|
|
826
850
|
var external_typeorm_ = __webpack_require__(158);
|
|
851
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/constants/index.ts
|
|
852
|
+
var constants = __webpack_require__(43);
|
|
827
853
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/decorators/log-action.decorator.ts
|
|
828
854
|
var log_action_decorator = __webpack_require__(946);
|
|
829
855
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/modules/utils/utils.service.ts
|
|
830
856
|
var utils_service = __webpack_require__(169);
|
|
857
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/utils/cache-tenant.util.ts
|
|
858
|
+
var cache_tenant_util = __webpack_require__(154);
|
|
831
859
|
// EXTERNAL MODULE: external "crypto"
|
|
832
860
|
var external_crypto_ = __webpack_require__(823);
|
|
833
861
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/middlewares/logger.middleware.ts + 2 modules
|
|
834
|
-
var logger_middleware = __webpack_require__(
|
|
862
|
+
var logger_middleware = __webpack_require__(591);
|
|
835
863
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/utils/event-pattern.util.ts
|
|
836
864
|
var event_pattern_util = __webpack_require__(456);
|
|
837
865
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/classes/event-bus.registry.ts
|
|
@@ -930,6 +958,7 @@ function api_service_class_ts_metadata(metadataKey, metadataValue) {
|
|
|
930
958
|
|
|
931
959
|
|
|
932
960
|
|
|
961
|
+
|
|
933
962
|
const DELETE_EVENT_ACTIONS = {
|
|
934
963
|
delete: 'deleted',
|
|
935
964
|
restore: 'restored',
|
|
@@ -963,6 +992,9 @@ class ApiService {
|
|
|
963
992
|
getDataSourceProvider() {
|
|
964
993
|
return this._dataSourceProvider;
|
|
965
994
|
}
|
|
995
|
+
/** Cached rows belong to the current tenant; pass this to every `UtilsService` cache helper. */ cacheTenant() {
|
|
996
|
+
return (0,cache_tenant_util/* .cacheTenantId */.q)(this._dataSourceProvider);
|
|
997
|
+
}
|
|
966
998
|
async ensureDataSourceRepository() {
|
|
967
999
|
if (!this.repositoryInitialized) {
|
|
968
1000
|
const provider = this.getDataSourceProvider();
|
|
@@ -1067,6 +1099,7 @@ class ApiService {
|
|
|
1067
1099
|
id: (0,external_typeorm_.In)(ids)
|
|
1068
1100
|
});
|
|
1069
1101
|
const selectArray = typeof select === 'string' ? select.split(',').map((s)=>s.trim()) : select;
|
|
1102
|
+
selectArray?.forEach((field)=>this.assertColumnProperty(field));
|
|
1070
1103
|
const { query: finalQuery, isRaw } = await this.getSelectQuery(query, user, selectArray);
|
|
1071
1104
|
let output;
|
|
1072
1105
|
if (isRaw) {
|
|
@@ -1077,7 +1110,7 @@ class ApiService {
|
|
|
1077
1110
|
const result = this.convertEntityListToResponseListDto(output, isRaw);
|
|
1078
1111
|
if (!result || !result.length) throw new common_.NotFoundException({
|
|
1079
1112
|
message: 'No Data Found',
|
|
1080
|
-
messageKey:
|
|
1113
|
+
messageKey: constants/* .ERROR_MESSAGES.NOT_FOUND */.UU.NOT_FOUND
|
|
1081
1114
|
});
|
|
1082
1115
|
return result;
|
|
1083
1116
|
} catch (error) {
|
|
@@ -1090,6 +1123,7 @@ class ApiService {
|
|
|
1090
1123
|
async findById(id, user, select) {
|
|
1091
1124
|
await this.ensureDataSourceRepository();
|
|
1092
1125
|
try {
|
|
1126
|
+
select?.forEach((field)=>this.assertColumnProperty(field));
|
|
1093
1127
|
const query = this.repository.createQueryBuilder(this.entityName);
|
|
1094
1128
|
query.where({
|
|
1095
1129
|
id
|
|
@@ -1098,7 +1132,7 @@ class ApiService {
|
|
|
1098
1132
|
let result;
|
|
1099
1133
|
let cacheKey = '';
|
|
1100
1134
|
if (this.isCacheable) {
|
|
1101
|
-
cacheKey = this.utilsService.getCacheKey(this.entityName, finalQuery.getQueryAndParameters(), id);
|
|
1135
|
+
cacheKey = this.utilsService.getCacheKey(this.entityName, finalQuery.getQueryAndParameters(), id, this.cacheTenant());
|
|
1102
1136
|
result = await this.cacheManager.get(cacheKey);
|
|
1103
1137
|
}
|
|
1104
1138
|
if (!result) {
|
|
@@ -1110,13 +1144,13 @@ class ApiService {
|
|
|
1110
1144
|
const singleOutput = await finalQuery.getOne();
|
|
1111
1145
|
if (!singleOutput) throw new common_.NotFoundException({
|
|
1112
1146
|
message: 'No Data Found',
|
|
1113
|
-
messageKey:
|
|
1147
|
+
messageKey: constants/* .ERROR_MESSAGES.NOT_FOUND */.UU.NOT_FOUND
|
|
1114
1148
|
});
|
|
1115
1149
|
result = this.convertEntityToResponseDto(singleOutput, false);
|
|
1116
1150
|
}
|
|
1117
1151
|
if (this.isCacheable) {
|
|
1118
1152
|
await this.cacheManager.set(cacheKey, result);
|
|
1119
|
-
await this.utilsService.trackCacheKey(cacheKey, this.entityName, this.cacheManager, id);
|
|
1153
|
+
await this.utilsService.trackCacheKey(cacheKey, this.entityName, this.cacheManager, id, this.cacheTenant());
|
|
1120
1154
|
}
|
|
1121
1155
|
}
|
|
1122
1156
|
return result;
|
|
@@ -1133,6 +1167,7 @@ class ApiService {
|
|
|
1133
1167
|
let data;
|
|
1134
1168
|
let total;
|
|
1135
1169
|
let isRaw = false;
|
|
1170
|
+
filterAndPaginationDto.select?.forEach((field)=>this.assertColumnProperty(field));
|
|
1136
1171
|
let query = this.repository.createQueryBuilder(this.entityName);
|
|
1137
1172
|
if (filterAndPaginationDto.filter) {
|
|
1138
1173
|
const { query: filterQuery, isRaw: filterIsRaw } = await this.getFilterQuery(query, filterAndPaginationDto.filter, user);
|
|
@@ -1171,7 +1206,7 @@ class ApiService {
|
|
|
1171
1206
|
raw: isRaw,
|
|
1172
1207
|
pagination: filterAndPaginationDto.pagination,
|
|
1173
1208
|
query: query.getQueryAndParameters()
|
|
1174
|
-
});
|
|
1209
|
+
}, undefined, this.cacheTenant());
|
|
1175
1210
|
const cached = await this.cacheManager.get(cacheKey);
|
|
1176
1211
|
if (cached) {
|
|
1177
1212
|
return cached;
|
|
@@ -1197,7 +1232,7 @@ class ApiService {
|
|
|
1197
1232
|
if (!(key in parameters)) {
|
|
1198
1233
|
throw new common_.InternalServerErrorException({
|
|
1199
1234
|
message: `Missing parameter value for: ${key}`,
|
|
1200
|
-
messageKey:
|
|
1235
|
+
messageKey: constants/* .SYSTEM_MESSAGES.MISSING_PARAMETER */.hg.MISSING_PARAMETER,
|
|
1201
1236
|
messageVariables: {
|
|
1202
1237
|
key
|
|
1203
1238
|
}
|
|
@@ -1219,7 +1254,7 @@ class ApiService {
|
|
|
1219
1254
|
};
|
|
1220
1255
|
if (this.isCacheable) {
|
|
1221
1256
|
await this.cacheManager.set(cacheKey, finalResponse);
|
|
1222
|
-
await this.utilsService.trackCacheKey(cacheKey, this.entityName, this.cacheManager);
|
|
1257
|
+
await this.utilsService.trackCacheKey(cacheKey, this.entityName, this.cacheManager, undefined, this.cacheTenant());
|
|
1223
1258
|
}
|
|
1224
1259
|
return finalResponse;
|
|
1225
1260
|
} catch (error) {
|
|
@@ -1301,10 +1336,10 @@ class ApiService {
|
|
|
1301
1336
|
});
|
|
1302
1337
|
}
|
|
1303
1338
|
async clearCacheForAll() {
|
|
1304
|
-
await this.utilsService.clearCache(this.entityName, this.cacheManager);
|
|
1339
|
+
await this.utilsService.clearCache(this.entityName, this.cacheManager, undefined, this.cacheTenant());
|
|
1305
1340
|
}
|
|
1306
1341
|
async clearCacheForId(entities) {
|
|
1307
|
-
await Promise.all(entities.map((item)=>this.utilsService.clearCache(this.entityName, this.cacheManager, item.id)));
|
|
1342
|
+
await Promise.all(entities.map((item)=>this.utilsService.clearCache(this.entityName, this.cacheManager, item.id, this.cacheTenant())));
|
|
1308
1343
|
}
|
|
1309
1344
|
handleError(error) {
|
|
1310
1345
|
if (error instanceof Error) {
|
|
@@ -1312,7 +1347,7 @@ class ApiService {
|
|
|
1312
1347
|
}
|
|
1313
1348
|
throw new common_.InternalServerErrorException({
|
|
1314
1349
|
message: typeof error === 'string' ? error : 'Unknown error',
|
|
1315
|
-
messageKey:
|
|
1350
|
+
messageKey: constants/* .ERROR_MESSAGES.INTERNAL */.UU.INTERNAL
|
|
1316
1351
|
});
|
|
1317
1352
|
}
|
|
1318
1353
|
ensureArray(value) {
|
|
@@ -1356,6 +1391,26 @@ class ApiService {
|
|
|
1356
1391
|
await qr.release();
|
|
1357
1392
|
}
|
|
1358
1393
|
}
|
|
1394
|
+
/**
|
|
1395
|
+
* Client-supplied filter/sort/select keys are interpolated into SQL as column identifiers
|
|
1396
|
+
* (identifiers cannot be bound as parameters), so every key must first be proven to be a
|
|
1397
|
+
* real column property of this entity - anything else is rejected outright.
|
|
1398
|
+
*/ assertColumnProperty(key) {
|
|
1399
|
+
if (!this.repository.metadata.findColumnWithPropertyName(key)) {
|
|
1400
|
+
throw new common_.BadRequestException({
|
|
1401
|
+
message: `'${key}' is not a valid field.`,
|
|
1402
|
+
messageKey: constants/* .ERROR_MESSAGES.VALIDATION */.UU.VALIDATION
|
|
1403
|
+
});
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
/** Validated `<alias>.<column> = :param` filter with a per-key parameter name, so several
|
|
1407
|
+
* filters in one request no longer overwrite each other's bound value. */ applyEqualsFilter(query, key, value) {
|
|
1408
|
+
this.assertColumnProperty(key);
|
|
1409
|
+
const param = `flt_${key}`;
|
|
1410
|
+
query.andWhere(`${this.entityName}.${key} = :${param}`, {
|
|
1411
|
+
[param]: value
|
|
1412
|
+
});
|
|
1413
|
+
}
|
|
1359
1414
|
async beforeInsertOperation(_dto, _user, _queryRunner) {}
|
|
1360
1415
|
async afterInsertOperation(_entity, _dto, _user, _queryRunner) {}
|
|
1361
1416
|
async beforeUpdateOperation(_dto, _user, _queryRunner) {}
|
|
@@ -1363,11 +1418,7 @@ class ApiService {
|
|
|
1363
1418
|
async beforeDeleteOperation(_dto, _user, _queryRunner) {}
|
|
1364
1419
|
async afterDeleteOperation(_entity, _dto, _user, _queryRunner) {}
|
|
1365
1420
|
async getFilterQuery(query, filter, _user) {
|
|
1366
|
-
Object.entries(filter).forEach(([key, value])=>
|
|
1367
|
-
query.andWhere(`${this.entityName}.${key} = :value`, {
|
|
1368
|
-
value
|
|
1369
|
-
});
|
|
1370
|
-
});
|
|
1421
|
+
Object.entries(filter).forEach(([key, value])=>this.applyEqualsFilter(query, key, value));
|
|
1371
1422
|
return {
|
|
1372
1423
|
query,
|
|
1373
1424
|
isRaw: false
|
|
@@ -1375,7 +1426,8 @@ class ApiService {
|
|
|
1375
1426
|
}
|
|
1376
1427
|
async getSortQuery(query, sort, _user) {
|
|
1377
1428
|
Object.entries(sort).forEach(([key, direction])=>{
|
|
1378
|
-
|
|
1429
|
+
this.assertColumnProperty(key);
|
|
1430
|
+
query.addOrderBy(`${this.entityName}.${key}`, direction === 'DESC' ? 'DESC' : 'ASC');
|
|
1379
1431
|
});
|
|
1380
1432
|
return {
|
|
1381
1433
|
query,
|
|
@@ -1383,7 +1435,10 @@ class ApiService {
|
|
|
1383
1435
|
};
|
|
1384
1436
|
}
|
|
1385
1437
|
async getSelectQuery(query, _user, select) {
|
|
1386
|
-
if (select && select.length)
|
|
1438
|
+
if (select && select.length) {
|
|
1439
|
+
select.forEach((field)=>this.assertColumnProperty(field));
|
|
1440
|
+
query.select(select.map((field)=>`${this.entityName}.${field}`));
|
|
1441
|
+
}
|
|
1387
1442
|
return {
|
|
1388
1443
|
query,
|
|
1389
1444
|
isRaw: false
|
|
@@ -1419,7 +1474,7 @@ class ApiService {
|
|
|
1419
1474
|
});
|
|
1420
1475
|
if (!existing) throw new common_.NotFoundException({
|
|
1421
1476
|
message: 'No such entity data found for update! Please, Try Again.',
|
|
1422
|
-
messageKey:
|
|
1477
|
+
messageKey: constants/* .ERROR_MESSAGES.NOT_FOUND */.UU.NOT_FOUND
|
|
1423
1478
|
});
|
|
1424
1479
|
return Object.assign(existing, d);
|
|
1425
1480
|
}
|
|
@@ -1559,7 +1614,7 @@ var permissions = __webpack_require__(975);
|
|
|
1559
1614
|
|
|
1560
1615
|
},
|
|
1561
1616
|
997(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
1562
|
-
/* import */ var _dtos_index_js__rspack_import_0 = __webpack_require__(
|
|
1617
|
+
/* import */ var _dtos_index_js__rspack_import_0 = __webpack_require__(746);
|
|
1563
1618
|
/* import */ var _nestjs_common__rspack_import_1 = __webpack_require__(157);
|
|
1564
1619
|
/* import */ var _nestjs_swagger__rspack_import_2 = __webpack_require__(176);
|
|
1565
1620
|
|
|
@@ -1730,7 +1785,7 @@ var constants = __webpack_require__(43);
|
|
|
1730
1785
|
946(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
1731
1786
|
/* import */ var _nestjs_common__rspack_import_0 = __webpack_require__(157);
|
|
1732
1787
|
/* import */ var _classes_winston_logger_class_js__rspack_import_1 = __webpack_require__(245);
|
|
1733
|
-
/* import */ var _middlewares_logger_middleware_js__rspack_import_2 = __webpack_require__(
|
|
1788
|
+
/* import */ var _middlewares_logger_middleware_js__rspack_import_2 = __webpack_require__(591);
|
|
1734
1789
|
|
|
1735
1790
|
|
|
1736
1791
|
|
|
@@ -2021,53 +2076,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
2021
2076
|
});
|
|
2022
2077
|
|
|
2023
2078
|
|
|
2024
|
-
},
|
|
2025
|
-
374(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
2026
|
-
/* import */ var _nestjs_common__rspack_import_0 = __webpack_require__(157);
|
|
2027
|
-
/* import */ var _constants_message_keys_js__rspack_import_1 = __webpack_require__(389);
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
class PermissionSystemUnavailableException extends _nestjs_common__rspack_import_0.InternalServerErrorException {
|
|
2031
|
-
constructor(){
|
|
2032
|
-
super({
|
|
2033
|
-
success: false,
|
|
2034
|
-
message: 'Permission system temporarily unavailable',
|
|
2035
|
-
messageKey: _constants_message_keys_js__rspack_import_1/* .ERROR_MESSAGES.PERMISSION_SYSTEM_UNAVAILABLE */.UU.PERMISSION_SYSTEM_UNAVAILABLE
|
|
2036
|
-
});
|
|
2037
|
-
}
|
|
2038
|
-
}
|
|
2039
|
-
class InsufficientPermissionsException extends _nestjs_common__rspack_import_0.ForbiddenException {
|
|
2040
|
-
constructor(missingPermissions, operator = 'AND'){
|
|
2041
|
-
const messageKey = operator === 'OR' ? _constants_message_keys_js__rspack_import_1/* .ERROR_MESSAGES.INSUFFICIENT_PERMISSIONS_OR */.UU.INSUFFICIENT_PERMISSIONS_OR : _constants_message_keys_js__rspack_import_1/* .ERROR_MESSAGES.INSUFFICIENT_PERMISSIONS */.UU.INSUFFICIENT_PERMISSIONS;
|
|
2042
|
-
super({
|
|
2043
|
-
success: false,
|
|
2044
|
-
message: 'Insufficient permissions',
|
|
2045
|
-
messageKey,
|
|
2046
|
-
messageVariables: {
|
|
2047
|
-
permissions: missingPermissions.join(', ')
|
|
2048
|
-
},
|
|
2049
|
-
missingPermissions,
|
|
2050
|
-
operator
|
|
2051
|
-
});
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
class NoPermissionsFoundException extends _nestjs_common__rspack_import_0.ForbiddenException {
|
|
2055
|
-
constructor(){
|
|
2056
|
-
super({
|
|
2057
|
-
success: false,
|
|
2058
|
-
message: 'No permissions found',
|
|
2059
|
-
messageKey: _constants_message_keys_js__rspack_import_1/* .ERROR_MESSAGES.NO_PERMISSIONS_FOUND */.UU.NO_PERMISSIONS_FOUND
|
|
2060
|
-
});
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
|
|
2064
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
2065
|
-
GS: () => (PermissionSystemUnavailableException),
|
|
2066
|
-
d$: () => (NoPermissionsFoundException),
|
|
2067
|
-
z8: () => (InsufficientPermissionsException)
|
|
2068
|
-
});
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
2079
|
},
|
|
2072
2080
|
510(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
2073
2081
|
|
|
@@ -2080,8 +2088,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
2080
2088
|
|
|
2081
2089
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/constants/index.ts
|
|
2082
2090
|
var constants = __webpack_require__(43);
|
|
2083
|
-
// EXTERNAL MODULE: ./projects/nestjs-shared/src/
|
|
2084
|
-
var
|
|
2091
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/middlewares/logger.middleware.ts + 2 modules
|
|
2092
|
+
var logger_middleware = __webpack_require__(591);
|
|
2085
2093
|
// EXTERNAL MODULE: external "@nestjs/common"
|
|
2086
2094
|
var common_ = __webpack_require__(157);
|
|
2087
2095
|
// EXTERNAL MODULE: external "@nestjs/core"
|
|
@@ -2116,6 +2124,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
2116
2124
|
|
|
2117
2125
|
|
|
2118
2126
|
|
|
2127
|
+
|
|
2119
2128
|
class JwtAuthGuard extends (0,__rspack_external__nestjs_passport_18907953.AuthGuard)('jwt') {
|
|
2120
2129
|
reflector;
|
|
2121
2130
|
// NOTE: @Inject(Reflector) required for bundled code - external classes need explicit injection
|
|
@@ -2137,9 +2146,10 @@ class JwtAuthGuard extends (0,__rspack_external__nestjs_passport_18907953.AuthGu
|
|
|
2137
2146
|
if (err || !user) {
|
|
2138
2147
|
throw err || new common_.UnauthorizedException({
|
|
2139
2148
|
message: 'Invalid or expired token',
|
|
2140
|
-
messageKey:
|
|
2149
|
+
messageKey: constants/* .AUTH_MESSAGES.TOKEN_INVALID */.mK.TOKEN_INVALID
|
|
2141
2150
|
});
|
|
2142
2151
|
}
|
|
2152
|
+
(0,logger_middleware/* .setRequestUser */.ZV)(user);
|
|
2143
2153
|
return user;
|
|
2144
2154
|
}
|
|
2145
2155
|
}
|
|
@@ -2180,6 +2190,7 @@ function optional_jwt_auth_guard_ts_param(paramIndex, decorator) {
|
|
|
2180
2190
|
|
|
2181
2191
|
|
|
2182
2192
|
|
|
2193
|
+
|
|
2183
2194
|
class OptionalJwtGuard extends (0,__rspack_external__nestjs_passport_18907953.AuthGuard)('jwt') {
|
|
2184
2195
|
reflector;
|
|
2185
2196
|
constructor(reflector){
|
|
@@ -2196,6 +2207,7 @@ class OptionalJwtGuard extends (0,__rspack_external__nestjs_passport_18907953.Au
|
|
|
2196
2207
|
return super.canActivate(context);
|
|
2197
2208
|
}
|
|
2198
2209
|
handleRequest(_err, user) {
|
|
2210
|
+
(0,logger_middleware/* .setRequestUser */.ZV)(user);
|
|
2199
2211
|
return user || undefined;
|
|
2200
2212
|
}
|
|
2201
2213
|
}
|
|
@@ -2263,7 +2275,7 @@ class PermissionGuard {
|
|
|
2263
2275
|
const user = request.user;
|
|
2264
2276
|
if (!user) throw new common_.UnauthorizedException({
|
|
2265
2277
|
message: 'Authentication required',
|
|
2266
|
-
messageKey:
|
|
2278
|
+
messageKey: constants/* .AUTH_MESSAGES.TOKEN_REQUIRED */.mK.TOKEN_REQUIRED
|
|
2267
2279
|
});
|
|
2268
2280
|
if (!this.permissionCacheService?.isCacheConfigured()) {
|
|
2269
2281
|
throw new permission_exception/* .PermissionSystemUnavailableException */.GS();
|
|
@@ -2449,8 +2461,6 @@ DeleteEmptyIdFromBodyInterceptor = _ts_decorate([
|
|
|
2449
2461
|
var hybrid_cache_class = __webpack_require__(375);
|
|
2450
2462
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/constants/index.ts
|
|
2451
2463
|
var constants = __webpack_require__(43);
|
|
2452
|
-
// EXTERNAL MODULE: ./projects/nestjs-shared/src/constants/message-keys.ts
|
|
2453
|
-
var message_keys = __webpack_require__(389);
|
|
2454
2464
|
;// CONCATENATED MODULE: ./projects/nestjs-shared/src/interceptors/idempotency.interceptor.ts
|
|
2455
2465
|
function idempotency_interceptor_ts_decorate(decorators, target, key, desc) {
|
|
2456
2466
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -2507,7 +2517,7 @@ class IdempotencyInterceptor {
|
|
|
2507
2517
|
throw new common_.ConflictException({
|
|
2508
2518
|
success: false,
|
|
2509
2519
|
message: 'Request is already being processed',
|
|
2510
|
-
messageKey:
|
|
2520
|
+
messageKey: constants/* .SYSTEM_MESSAGES.DUPLICATE_REQUEST */.hg.DUPLICATE_REQUEST
|
|
2511
2521
|
});
|
|
2512
2522
|
}
|
|
2513
2523
|
// Return cached response
|
|
@@ -2596,26 +2606,21 @@ function set_user_field_on_body_interceptor_ts_decorate(decorators, target, key,
|
|
|
2596
2606
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2597
2607
|
}
|
|
2598
2608
|
|
|
2599
|
-
/**
|
|
2600
|
-
* Factory function to create interceptors that set user ID fields on request body
|
|
2601
|
-
* @param fieldName - The field name to set (e.g., 'createdById', 'updatedById', 'deletedById')
|
|
2602
|
-
*/ function createSetUserFieldInterceptor(fieldName) {
|
|
2609
|
+
/** Stamps `fieldName` on the body from the authenticated user; a client-sent value is always dropped. */ function createSetUserFieldInterceptor(fieldName) {
|
|
2603
2610
|
let SetUserFieldOnBody = class SetUserFieldOnBody {
|
|
2604
2611
|
intercept(context, next) {
|
|
2605
2612
|
const request = context.switchToHttp().getRequest();
|
|
2606
|
-
const
|
|
2607
|
-
|
|
2608
|
-
if (Array.isArray(
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
}
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
};
|
|
2618
|
-
}
|
|
2613
|
+
const userId = request?.user?.id;
|
|
2614
|
+
const stamp = (item)=>{
|
|
2615
|
+
if (typeof item !== 'object' || item === null || Array.isArray(item)) return item;
|
|
2616
|
+
const { [fieldName]: _clientValue, ...rest } = item;
|
|
2617
|
+
return userId ? {
|
|
2618
|
+
...rest,
|
|
2619
|
+
[fieldName]: userId
|
|
2620
|
+
} : rest;
|
|
2621
|
+
};
|
|
2622
|
+
if (request) {
|
|
2623
|
+
request.body = Array.isArray(request.body) ? request.body.map(stamp) : stamp(request.body);
|
|
2619
2624
|
}
|
|
2620
2625
|
return next.handle();
|
|
2621
2626
|
}
|
|
@@ -2625,9 +2630,9 @@ function set_user_field_on_body_interceptor_ts_decorate(decorators, target, key,
|
|
|
2625
2630
|
], SetUserFieldOnBody);
|
|
2626
2631
|
return SetUserFieldOnBody;
|
|
2627
2632
|
}
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2633
|
+
const SetCreatedByOnBody = createSetUserFieldInterceptor('createdById');
|
|
2634
|
+
const SetUpdateByOnBody = createSetUserFieldInterceptor('updatedById');
|
|
2635
|
+
const SetDeletedByOnBody = createSetUserFieldInterceptor('deletedById');
|
|
2631
2636
|
|
|
2632
2637
|
// EXTERNAL MODULE: ./projects/nestjs-shared/src/modules/utils/utils.service.ts
|
|
2633
2638
|
var utils_service = __webpack_require__(169);
|
|
@@ -2703,9 +2708,127 @@ Slug = slug_interceptor_ts_decorate([
|
|
|
2703
2708
|
|
|
2704
2709
|
|
|
2705
2710
|
},
|
|
2706
|
-
|
|
2711
|
+
928(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
2712
|
+
|
|
2713
|
+
// EXPORTS
|
|
2714
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
2715
|
+
gG: () => (/* reexport */ AUDIT_BODY_KEYS),
|
|
2716
|
+
d0: () => (/* reexport */ DEFAULT_VALIDATION_OPTIONS),
|
|
2717
|
+
zT: () => (/* reexport */ DtoBodyValidationPipe)
|
|
2718
|
+
});
|
|
2719
|
+
|
|
2720
|
+
// EXTERNAL MODULE: external "@nestjs/common"
|
|
2721
|
+
var common_ = __webpack_require__(157);
|
|
2722
|
+
// EXTERNAL MODULE: external "class-validator"
|
|
2723
|
+
var external_class_validator_ = __webpack_require__(421);
|
|
2724
|
+
// EXTERNAL MODULE: ./projects/nestjs-shared/src/constants/message-keys.ts
|
|
2725
|
+
var message_keys = __webpack_require__(389);
|
|
2726
|
+
;// CONCATENATED MODULE: ./projects/nestjs-shared/src/pipes/dto-body-validation.pipe.ts
|
|
2727
|
+
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
const DEFAULT_VALIDATION_OPTIONS = {
|
|
2731
|
+
transform: true,
|
|
2732
|
+
whitelist: true,
|
|
2733
|
+
forbidNonWhitelisted: true,
|
|
2734
|
+
transformOptions: {
|
|
2735
|
+
enableImplicitConversion: false
|
|
2736
|
+
}
|
|
2737
|
+
};
|
|
2738
|
+
const AUDIT_BODY_KEYS = [
|
|
2739
|
+
'createdById',
|
|
2740
|
+
'updatedById',
|
|
2741
|
+
'deletedById'
|
|
2742
|
+
];
|
|
2743
|
+
/**
|
|
2744
|
+
* Validates a generic controller body against its concrete DTO class: a generic
|
|
2745
|
+
* `@Body() dto: T` reflects as `Object`, so the global ValidationPipe skips it.
|
|
2746
|
+
* Audit keys are never taken from the client: `stampedKeys` (written by the endpoint's
|
|
2747
|
+
* SetCreatedByOnBody / SetUpdateByOnBody interceptors, which run first) are kept, any other
|
|
2748
|
+
* audit key is dropped. A `slug` the DTO does not declare is the Slug interceptor's and is kept.
|
|
2749
|
+
*/ class DtoBodyValidationPipe {
|
|
2750
|
+
resolveDto;
|
|
2751
|
+
stampedKeys;
|
|
2752
|
+
isArray;
|
|
2753
|
+
options;
|
|
2754
|
+
pipes = new Map();
|
|
2755
|
+
constructor(resolveDto, stampedKeys, isArray = false, options = DEFAULT_VALIDATION_OPTIONS){
|
|
2756
|
+
this.resolveDto = resolveDto;
|
|
2757
|
+
this.stampedKeys = stampedKeys;
|
|
2758
|
+
this.isArray = isArray;
|
|
2759
|
+
this.options = options;
|
|
2760
|
+
}
|
|
2761
|
+
static for(dto, stampedKeys, isArray = false) {
|
|
2762
|
+
return new DtoBodyValidationPipe(()=>dto, stampedKeys, isArray);
|
|
2763
|
+
}
|
|
2764
|
+
async transform(value, metadata) {
|
|
2765
|
+
if (!this.isArray) return this.validateItem(value, metadata);
|
|
2766
|
+
if (!Array.isArray(value)) throw new common_.BadRequestException({
|
|
2767
|
+
message: 'Request body must be an array',
|
|
2768
|
+
messageKey: message_keys/* .ERROR_MESSAGES.VALIDATION */.UU.VALIDATION
|
|
2769
|
+
});
|
|
2770
|
+
return Promise.all(value.map((item)=>this.validateItem(item, metadata)));
|
|
2771
|
+
}
|
|
2772
|
+
async validateItem(item, metadata) {
|
|
2773
|
+
if (item === null || typeof item !== 'object' || Array.isArray(item)) {
|
|
2774
|
+
throw new common_.BadRequestException({
|
|
2775
|
+
message: 'Request body item must be an object',
|
|
2776
|
+
messageKey: message_keys/* .ERROR_MESSAGES.VALIDATION */.UU.VALIDATION
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
const dto = this.resolveDto(item);
|
|
2780
|
+
const rest = {
|
|
2781
|
+
...item
|
|
2782
|
+
};
|
|
2783
|
+
const injected = {};
|
|
2784
|
+
for (const key of AUDIT_BODY_KEYS){
|
|
2785
|
+
if (!(key in rest)) continue;
|
|
2786
|
+
if (this.stampedKeys.includes(key)) injected[key] = rest[key];
|
|
2787
|
+
delete rest[key];
|
|
2788
|
+
}
|
|
2789
|
+
if ('slug' in rest && !declaresProperty(dto, 'slug')) {
|
|
2790
|
+
injected['slug'] = rest['slug'];
|
|
2791
|
+
delete rest['slug'];
|
|
2792
|
+
}
|
|
2793
|
+
const validated = await this.pipeFor(dto).transform(rest, {
|
|
2794
|
+
...metadata,
|
|
2795
|
+
metatype: dto
|
|
2796
|
+
});
|
|
2797
|
+
return Object.assign(validated, injected);
|
|
2798
|
+
}
|
|
2799
|
+
pipeFor(dto) {
|
|
2800
|
+
let pipe = this.pipes.get(dto);
|
|
2801
|
+
if (!pipe) {
|
|
2802
|
+
pipe = new common_.ValidationPipe({
|
|
2803
|
+
...this.options,
|
|
2804
|
+
expectedType: dto
|
|
2805
|
+
});
|
|
2806
|
+
this.pipes.set(dto, pipe);
|
|
2807
|
+
}
|
|
2808
|
+
return pipe;
|
|
2809
|
+
}
|
|
2810
|
+
}
|
|
2811
|
+
function declaresProperty(dto, key) {
|
|
2812
|
+
return (0,external_class_validator_.getMetadataStorage)().getTargetValidationMetadatas(dto, '', true, false).some((m)=>m.propertyName === key);
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
;// CONCATENATED MODULE: ./projects/nestjs-shared/src/pipes/index.ts
|
|
2816
|
+
|
|
2817
|
+
|
|
2818
|
+
|
|
2819
|
+
},
|
|
2820
|
+
154(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
2821
|
+
/**
|
|
2822
|
+
* The tenant a cache key belongs to: the provider's current tenant in multi-tenant mode, else
|
|
2823
|
+
* undefined. A single database never prefixes, so a stray tenant header cannot split its cache.
|
|
2824
|
+
*/ function cacheTenantId(provider) {
|
|
2825
|
+
if (!provider?.isMultiTenant?.()) return undefined;
|
|
2826
|
+
return provider.getCurrentTenantId?.() ?? undefined;
|
|
2827
|
+
}
|
|
2707
2828
|
|
|
2708
|
-
|
|
2829
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
2830
|
+
q: () => (cacheTenantId)
|
|
2831
|
+
});
|
|
2709
2832
|
|
|
2710
2833
|
|
|
2711
2834
|
},
|