@flusys/nestjs-shared 1.1.0-beta → 1.2.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -1330
- package/cjs/classes/api-controller.class.js +325 -49
- package/cjs/classes/api-service.class.js +271 -149
- package/cjs/classes/handle-custome-db.js +37 -0
- package/cjs/classes/index.js +2 -2
- package/cjs/classes/winston.logger.class.js +103 -70
- package/cjs/constants/index.js +15 -4
- package/cjs/constants/message-keys.js +68 -0
- package/cjs/constants/permissions.js +287 -0
- package/cjs/decorators/api-response.decorator.js +2 -3
- package/cjs/decorators/index.js +1 -0
- package/cjs/decorators/log-action.decorator.js +149 -0
- package/cjs/decorators/require-permission.decorator.js +5 -5
- package/cjs/dtos/delete.dto.js +10 -0
- package/cjs/dtos/filter-and-pagination.dto.js +24 -34
- 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/pagination.dto.js +4 -8
- package/cjs/dtos/response-payload.dto.js +68 -112
- package/cjs/entities/identity.js +12 -6
- package/cjs/entities/index.js +1 -0
- package/cjs/entities/raw-type.js +4 -0
- package/cjs/entities/user-root.js +15 -15
- 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 +88 -148
- package/cjs/index.js +2 -0
- package/cjs/interceptors/idempotency.interceptor.js +1 -1
- package/cjs/interceptors/index.js +1 -4
- package/cjs/interceptors/set-user-field-on-body.interceptor.js +60 -0
- package/cjs/interceptors/slug.interceptor.js +30 -9
- package/cjs/interfaces/datasource.interface.js +4 -0
- package/cjs/interfaces/event-manager-adapter.interface.js +11 -0
- package/cjs/interfaces/index.js +4 -2
- package/cjs/interfaces/module-config.interface.js +4 -0
- package/cjs/interfaces/notification-adapter.interface.js +11 -0
- package/cjs/interfaces/permission.interface.js +1 -1
- package/cjs/middlewares/logger.middleware.js +133 -115
- package/cjs/modules/cache/cache.module.js +3 -3
- package/cjs/modules/datasource/index.js +0 -1
- package/cjs/modules/datasource/multi-tenant-datasource.service.js +60 -183
- package/cjs/modules/utils/utils.service.js +27 -206
- package/cjs/utils/date-time.util.js +94 -0
- package/cjs/utils/html-sanitizer.util.js +64 -0
- package/cjs/utils/index.js +5 -1
- package/cjs/utils/query-helpers.util.js +60 -0
- package/cjs/utils/request.util.js +96 -0
- package/cjs/utils/string.util.js +63 -0
- package/classes/api-controller.class.d.ts +16 -8
- package/classes/api-service.class.d.ts +30 -25
- package/classes/handle-custome-db.d.ts +3 -0
- package/classes/index.d.ts +2 -2
- package/classes/winston.logger.class.d.ts +1 -0
- package/constants/index.d.ts +2 -1
- package/constants/message-keys.d.ts +45 -0
- package/constants/permissions.d.ts +306 -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 -0
- package/decorators/log-action.decorator.d.ts +8 -0
- package/decorators/require-permission.decorator.d.ts +2 -2
- package/dtos/delete.dto.d.ts +1 -0
- package/dtos/filter-and-pagination.dto.d.ts +0 -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 -20
- 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 +326 -50
- package/fesm/classes/api-service.class.js +274 -152
- package/fesm/classes/handle-custome-db.js +19 -0
- package/fesm/classes/index.js +3 -2
- package/fesm/classes/winston.logger.class.js +100 -68
- package/fesm/constants/index.js +4 -1
- package/fesm/constants/message-keys.js +49 -0
- package/fesm/constants/permissions.js +200 -0
- package/fesm/decorators/api-response.decorator.js +3 -21
- package/fesm/decorators/index.js +1 -0
- package/fesm/decorators/log-action.decorator.js +139 -0
- package/fesm/decorators/require-permission.decorator.js +17 -65
- package/fesm/dtos/delete.dto.js +12 -2
- package/fesm/dtos/filter-and-pagination.dto.js +26 -47
- 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/pagination.dto.js +4 -8
- package/fesm/dtos/response-payload.dto.js +68 -103
- package/fesm/entities/identity.js +12 -6
- package/fesm/entities/index.js +1 -0
- package/fesm/entities/raw-type.js +1 -0
- package/fesm/entities/user-root.js +15 -15
- 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 +90 -150
- package/fesm/index.js +2 -0
- package/fesm/interceptors/idempotency.interceptor.js +2 -2
- package/fesm/interceptors/index.js +1 -4
- package/fesm/interceptors/set-user-field-on-body.interceptor.js +39 -0
- package/fesm/interceptors/slug.interceptor.js +31 -10
- package/fesm/interfaces/datasource.interface.js +1 -0
- package/fesm/interfaces/event-manager-adapter.interface.js +1 -0
- package/fesm/interfaces/index.js +4 -2
- package/fesm/interfaces/module-config.interface.js +5 -0
- package/fesm/interfaces/notification-adapter.interface.js +1 -0
- package/fesm/interfaces/permission.interface.js +1 -3
- package/fesm/middlewares/logger.middleware.js +133 -109
- package/fesm/modules/cache/cache.module.js +2 -2
- package/fesm/modules/datasource/index.js +0 -1
- package/fesm/modules/datasource/multi-tenant-datasource.service.js +61 -184
- package/fesm/modules/utils/utils.service.js +27 -206
- package/fesm/utils/date-time.util.js +70 -0
- package/fesm/utils/html-sanitizer.util.js +69 -0
- package/fesm/utils/index.js +5 -1
- package/fesm/utils/query-helpers.util.js +85 -0
- package/fesm/utils/request.util.js +81 -0
- package/fesm/utils/string.util.js +71 -0
- package/filters/global-exception.filter.d.ts +9 -0
- package/filters/index.d.ts +1 -0
- package/guards/permission.guard.d.ts +4 -6
- package/index.d.ts +2 -0
- package/interceptors/idempotency.interceptor.d.ts +1 -1
- package/interceptors/index.d.ts +1 -4
- package/interceptors/set-user-field-on-body.interceptor.d.ts +5 -0
- package/interceptors/slug.interceptor.d.ts +2 -1
- package/interfaces/api.interface.d.ts +4 -2
- package/interfaces/datasource.interface.d.ts +5 -0
- package/interfaces/event-manager-adapter.interface.d.ts +43 -0
- package/interfaces/identity.interface.d.ts +4 -4
- package/interfaces/index.d.ts +4 -2
- package/interfaces/logged-user-info.interface.d.ts +0 -2
- package/interfaces/module-config.interface.d.ts +6 -0
- package/interfaces/notification-adapter.interface.d.ts +21 -0
- package/interfaces/permission.interface.d.ts +13 -9
- package/middlewares/logger.middleware.d.ts +2 -2
- package/modules/datasource/index.d.ts +0 -1
- package/modules/datasource/multi-tenant-datasource.service.d.ts +5 -16
- package/modules/utils/utils.service.d.ts +3 -14
- package/package.json +21 -14
- package/utils/date-time.util.d.ts +8 -0
- package/utils/html-sanitizer.util.d.ts +2 -0
- package/utils/index.d.ts +5 -1
- package/utils/query-helpers.util.d.ts +16 -0
- package/utils/request.util.d.ts +6 -0
- package/utils/string.util.d.ts +2 -0
- package/cjs/classes/request-scoped-api.service.js +0 -61
- package/cjs/classes/winston-logger-adapter.class.js +0 -121
- package/cjs/interceptors/query-performance.interceptor.js +0 -66
- package/cjs/interceptors/set-create-by-on-body.interceptor.js +0 -40
- package/cjs/interceptors/set-delete-by-on-body.interceptor.js +0 -40
- package/cjs/interceptors/set-update-by-on-body.interceptor.js +0 -40
- package/cjs/interfaces/base-query.interface.js +0 -6
- package/cjs/interfaces/logger.interface.js +0 -7
- package/cjs/modules/datasource/datasource.module.js +0 -120
- package/cjs/utils/error-handler.util.js +0 -67
- package/classes/request-scoped-api.service.d.ts +0 -13
- package/classes/winston-logger-adapter.class.d.ts +0 -20
- package/fesm/classes/request-scoped-api.service.js +0 -51
- package/fesm/classes/winston-logger-adapter.class.js +0 -124
- package/fesm/interceptors/query-performance.interceptor.js +0 -56
- package/fesm/interceptors/set-create-by-on-body.interceptor.js +0 -30
- package/fesm/interceptors/set-delete-by-on-body.interceptor.js +0 -30
- package/fesm/interceptors/set-update-by-on-body.interceptor.js +0 -30
- package/fesm/interfaces/base-query.interface.js +0 -3
- package/fesm/interfaces/logger.interface.js +0 -4
- package/fesm/modules/datasource/datasource.module.js +0 -110
- package/fesm/utils/error-handler.util.js +0 -59
- package/interceptors/query-performance.interceptor.d.ts +0 -8
- package/interceptors/set-create-by-on-body.interceptor.d.ts +0 -5
- package/interceptors/set-delete-by-on-body.interceptor.d.ts +0 -5
- package/interceptors/set-update-by-on-body.interceptor.d.ts +0 -5
- package/interfaces/base-query.interface.d.ts +0 -7
- package/interfaces/logger.interface.d.ts +0 -7
- package/modules/datasource/datasource.module.d.ts +0 -18
- package/utils/error-handler.util.d.ts +0 -24
|
@@ -4,11 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./delete-empty-id-from-body.interceptor"), exports);
|
|
6
6
|
_export_star(require("./idempotency.interceptor"), exports);
|
|
7
|
-
_export_star(require("./query-performance.interceptor"), exports);
|
|
8
7
|
_export_star(require("./response-meta.interceptor"), exports);
|
|
9
|
-
_export_star(require("./set-
|
|
10
|
-
_export_star(require("./set-delete-by-on-body.interceptor"), exports);
|
|
11
|
-
_export_star(require("./set-update-by-on-body.interceptor"), exports);
|
|
8
|
+
_export_star(require("./set-user-field-on-body.interceptor"), exports);
|
|
12
9
|
_export_star(require("./slug.interceptor"), exports);
|
|
13
10
|
function _export_star(from, to) {
|
|
14
11
|
Object.keys(from).forEach(function(k) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get SetCreatedByOnBody () {
|
|
13
|
+
return SetCreatedByOnBody;
|
|
14
|
+
},
|
|
15
|
+
get SetDeletedByOnBody () {
|
|
16
|
+
return SetDeletedByOnBody;
|
|
17
|
+
},
|
|
18
|
+
get SetUpdateByOnBody () {
|
|
19
|
+
return SetUpdateByOnBody;
|
|
20
|
+
},
|
|
21
|
+
get createSetUserFieldInterceptor () {
|
|
22
|
+
return createSetUserFieldInterceptor;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
const _common = require("@nestjs/common");
|
|
26
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
27
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
28
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
29
|
+
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;
|
|
30
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31
|
+
}
|
|
32
|
+
function createSetUserFieldInterceptor(fieldName) {
|
|
33
|
+
let SetUserFieldOnBody = class SetUserFieldOnBody {
|
|
34
|
+
intercept(context, next) {
|
|
35
|
+
const request = context.switchToHttp().getRequest();
|
|
36
|
+
const user = request?.user;
|
|
37
|
+
if (user) {
|
|
38
|
+
if (Array.isArray(request.body)) {
|
|
39
|
+
request.body = request.body.map((item)=>({
|
|
40
|
+
...item,
|
|
41
|
+
[fieldName]: user.id
|
|
42
|
+
}));
|
|
43
|
+
} else if (typeof request.body === 'object' && request.body !== null) {
|
|
44
|
+
request.body = {
|
|
45
|
+
...request.body,
|
|
46
|
+
[fieldName]: user.id
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return next.handle();
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
SetUserFieldOnBody = _ts_decorate([
|
|
54
|
+
(0, _common.Injectable)()
|
|
55
|
+
], SetUserFieldOnBody);
|
|
56
|
+
return SetUserFieldOnBody;
|
|
57
|
+
}
|
|
58
|
+
const SetCreatedByOnBody = createSetUserFieldInterceptor('createdById');
|
|
59
|
+
const SetUpdateByOnBody = createSetUserFieldInterceptor('updatedById');
|
|
60
|
+
const SetDeletedByOnBody = createSetUserFieldInterceptor('deletedById');
|
|
@@ -29,26 +29,47 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
29
29
|
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;
|
|
30
30
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31
31
|
}
|
|
32
|
+
function _ts_metadata(k, v) {
|
|
33
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
34
|
+
}
|
|
35
|
+
function _ts_param(paramIndex, decorator) {
|
|
36
|
+
return function(target, key) {
|
|
37
|
+
decorator(target, key, paramIndex);
|
|
38
|
+
};
|
|
39
|
+
}
|
|
32
40
|
let Slug = class Slug {
|
|
33
41
|
intercept(context, next) {
|
|
34
42
|
const request = context.switchToHttp().getRequest();
|
|
35
43
|
if (Array.isArray(request.body)) {
|
|
36
|
-
request.body = request.body.map((item)=>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
request.body = request.body.map((item)=>{
|
|
45
|
+
// Only generate slug if not provided and name exists
|
|
46
|
+
if (!item.slug && item?.name) {
|
|
47
|
+
return {
|
|
48
|
+
...item,
|
|
49
|
+
slug: this.utilsService.transformToSlug(item.name)
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return item;
|
|
53
|
+
});
|
|
54
|
+
} else if (!request.body?.slug && request.body?.name) {
|
|
55
|
+
// Only generate slug if not provided and name exists
|
|
41
56
|
request.body = {
|
|
42
57
|
...request.body,
|
|
43
|
-
slug:
|
|
58
|
+
slug: this.utilsService.transformToSlug(request.body.name)
|
|
44
59
|
};
|
|
45
60
|
}
|
|
46
61
|
return next.handle();
|
|
47
62
|
}
|
|
48
|
-
constructor(){
|
|
49
|
-
_define_property(this, "utilsService",
|
|
63
|
+
constructor(utilsService){
|
|
64
|
+
_define_property(this, "utilsService", void 0);
|
|
65
|
+
this.utilsService = utilsService;
|
|
50
66
|
}
|
|
51
67
|
};
|
|
52
68
|
Slug = _ts_decorate([
|
|
53
|
-
(0, _common.Injectable)()
|
|
69
|
+
(0, _common.Injectable)(),
|
|
70
|
+
_ts_param(0, (0, _common.Inject)(_utilsservice.UtilsService)),
|
|
71
|
+
_ts_metadata("design:type", Function),
|
|
72
|
+
_ts_metadata("design:paramtypes", [
|
|
73
|
+
typeof _utilsservice.UtilsService === "undefined" ? Object : _utilsservice.UtilsService
|
|
74
|
+
])
|
|
54
75
|
], Slug);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "EVENT_MANAGER_ADAPTER", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return EVENT_MANAGER_ADAPTER;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const EVENT_MANAGER_ADAPTER = 'EVENT_MANAGER_ADAPTER';
|
package/cjs/interfaces/index.js
CHANGED
|
@@ -3,10 +3,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
5
|
_export_star(require("./api.interface"), exports);
|
|
6
|
-
_export_star(require("./
|
|
6
|
+
_export_star(require("./datasource.interface"), exports);
|
|
7
|
+
_export_star(require("./event-manager-adapter.interface"), exports);
|
|
7
8
|
_export_star(require("./identity.interface"), exports);
|
|
8
9
|
_export_star(require("./logged-user-info.interface"), exports);
|
|
9
|
-
_export_star(require("./
|
|
10
|
+
_export_star(require("./module-config.interface"), exports);
|
|
11
|
+
_export_star(require("./notification-adapter.interface"), exports);
|
|
10
12
|
_export_star(require("./permission.interface"), exports);
|
|
11
13
|
function _export_star(from, to) {
|
|
12
14
|
Object.keys(from).forEach(function(k) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "NOTIFICATION_ADAPTER", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return NOTIFICATION_ADAPTER;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const NOTIFICATION_ADAPTER = 'NOTIFICATION_ADAPTER';
|
|
@@ -26,12 +26,6 @@ _export(exports, {
|
|
|
26
26
|
},
|
|
27
27
|
get requestContext () {
|
|
28
28
|
return requestContext;
|
|
29
|
-
},
|
|
30
|
-
get setCompanyId () {
|
|
31
|
-
return setCompanyId;
|
|
32
|
-
},
|
|
33
|
-
get setUserId () {
|
|
34
|
-
return setUserId;
|
|
35
29
|
}
|
|
36
30
|
});
|
|
37
31
|
const _config = require("@flusys/nestjs-core/config");
|
|
@@ -60,44 +54,87 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
60
54
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
61
55
|
}
|
|
62
56
|
// Configuration
|
|
63
|
-
const
|
|
57
|
+
const logConfig = _config.envConfig.getLogConfig();
|
|
58
|
+
const IS_DEBUG = logConfig.level === 'debug';
|
|
59
|
+
const DISABLE_HTTP_LOGGING = logConfig.disableHttpLogging;
|
|
64
60
|
const TENANT_ID_HEADER = 'x-tenant-id';
|
|
65
61
|
const EXCLUDED_PATHS = [
|
|
66
62
|
'/health',
|
|
67
63
|
'/metrics',
|
|
68
64
|
'/favicon.ico'
|
|
69
65
|
];
|
|
70
|
-
const EXCLUDED_HEADERS = [
|
|
71
|
-
'authorization',
|
|
72
|
-
'cookie',
|
|
73
|
-
'x-api-key'
|
|
74
|
-
];
|
|
75
66
|
const MAX_BODY_LOG_SIZE = 1000;
|
|
76
67
|
const requestContext = new _async_hooks.AsyncLocalStorage();
|
|
77
68
|
const getRequestId = ()=>requestContext.getStore()?.requestId;
|
|
78
69
|
const getTenantId = ()=>requestContext.getStore()?.tenantId;
|
|
79
70
|
const getUserId = ()=>requestContext.getStore()?.userId;
|
|
80
71
|
const getCompanyId = ()=>requestContext.getStore()?.companyId;
|
|
81
|
-
const setUserId = (userId)=>{
|
|
82
|
-
const store = requestContext.getStore();
|
|
83
|
-
if (store) store.userId = userId;
|
|
84
|
-
};
|
|
85
|
-
const setCompanyId = (companyId)=>{
|
|
86
|
-
const store = requestContext.getStore();
|
|
87
|
-
if (store) store.companyId = companyId;
|
|
88
|
-
};
|
|
89
72
|
// Helper Functions
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
73
|
+
function summarizeRequestBody(body) {
|
|
74
|
+
if (!body) return undefined;
|
|
75
|
+
const parsed = typeof body === 'string' ? tryParseJson(body) : body;
|
|
76
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
77
|
+
const str = String(body);
|
|
78
|
+
return str.length > MAX_BODY_LOG_SIZE ? str.substring(0, MAX_BODY_LOG_SIZE) + '...' : str;
|
|
94
79
|
}
|
|
95
|
-
|
|
80
|
+
// For API request bodies, provide a concise summary
|
|
81
|
+
const summary = {};
|
|
82
|
+
// Pagination info
|
|
83
|
+
if (parsed.pagination) {
|
|
84
|
+
summary.page = parsed.pagination.currentPage;
|
|
85
|
+
summary.pageSize = parsed.pagination.pageSize;
|
|
86
|
+
}
|
|
87
|
+
// Filter keys only (not values - may contain sensitive data)
|
|
88
|
+
if (parsed.filter && typeof parsed.filter === 'object') {
|
|
89
|
+
const filterKeys = Object.keys(parsed.filter);
|
|
90
|
+
if (filterKeys.length > 0) summary.filterKeys = filterKeys;
|
|
91
|
+
}
|
|
92
|
+
// Select fields count
|
|
93
|
+
if (Array.isArray(parsed.select) && parsed.select.length > 0) {
|
|
94
|
+
summary.selectCount = parsed.select.length;
|
|
95
|
+
}
|
|
96
|
+
// Sort keys
|
|
97
|
+
if (parsed.sort && typeof parsed.sort === 'object') {
|
|
98
|
+
const sortKeys = Object.keys(parsed.sort);
|
|
99
|
+
if (sortKeys.length > 0) summary.sortKeys = sortKeys;
|
|
100
|
+
}
|
|
101
|
+
// ID for single item operations
|
|
102
|
+
if (parsed.id) summary.id = parsed.id;
|
|
103
|
+
// IDs for bulk operations
|
|
104
|
+
if (Array.isArray(parsed.ids)) summary.idsCount = parsed.ids.length;
|
|
105
|
+
return Object.keys(summary).length > 0 ? JSON.stringify(summary) : '{}';
|
|
96
106
|
}
|
|
97
|
-
function
|
|
107
|
+
function summarizeResponseBody(body) {
|
|
98
108
|
if (!body) return undefined;
|
|
99
|
-
const
|
|
100
|
-
|
|
109
|
+
const parsed = typeof body === 'string' ? tryParseJson(body) : body;
|
|
110
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
111
|
+
const str = String(body);
|
|
112
|
+
return str.length > MAX_BODY_LOG_SIZE ? str.substring(0, MAX_BODY_LOG_SIZE) + '...' : str;
|
|
113
|
+
}
|
|
114
|
+
const summary = {};
|
|
115
|
+
if ('success' in parsed) summary.success = parsed.success;
|
|
116
|
+
if ('message' in parsed) summary.message = parsed.message;
|
|
117
|
+
if ('code' in parsed) summary.code = parsed.code;
|
|
118
|
+
if (Array.isArray(parsed.data)) {
|
|
119
|
+
summary.dataCount = parsed.data.length;
|
|
120
|
+
} else if (parsed.data && typeof parsed.data === 'object') {
|
|
121
|
+
summary.hasData = true;
|
|
122
|
+
}
|
|
123
|
+
if (parsed.meta) {
|
|
124
|
+
summary.total = parsed.meta.total;
|
|
125
|
+
summary.page = parsed.meta.page;
|
|
126
|
+
}
|
|
127
|
+
if (parsed.errors) {
|
|
128
|
+
summary.errorsCount = Array.isArray(parsed.errors) ? parsed.errors.length : 1;
|
|
129
|
+
}
|
|
130
|
+
return JSON.stringify(summary);
|
|
131
|
+
}
|
|
132
|
+
function tryParseJson(str) {
|
|
133
|
+
try {
|
|
134
|
+
return JSON.parse(str);
|
|
135
|
+
} catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
101
138
|
}
|
|
102
139
|
function getClientIp(req) {
|
|
103
140
|
return req.headers['x-forwarded-for']?.split(',')[0] || req.socket?.remoteAddress || 'unknown';
|
|
@@ -107,136 +144,117 @@ let LoggerMiddleware = class LoggerMiddleware {
|
|
|
107
144
|
const requestId = req.headers[_constants.REQUEST_ID_HEADER] || (0, _uuid.v4)();
|
|
108
145
|
const tenantId = req.headers[TENANT_ID_HEADER];
|
|
109
146
|
const startTime = Date.now();
|
|
110
|
-
// Set response header
|
|
111
147
|
res.setHeader(_constants.REQUEST_ID_HEADER, requestId);
|
|
112
|
-
// Create context
|
|
113
148
|
const context = {
|
|
114
149
|
requestId,
|
|
115
150
|
tenantId,
|
|
116
151
|
startTime
|
|
117
152
|
};
|
|
118
|
-
// Run in AsyncLocalStorage context
|
|
119
153
|
requestContext.run(context, ()=>{
|
|
120
|
-
|
|
121
|
-
const shouldSkipLogging = EXCLUDED_PATHS.some((path)=>req.originalUrl.startsWith(path));
|
|
154
|
+
const shouldSkipLogging = DISABLE_HTTP_LOGGING || EXCLUDED_PATHS.some((path)=>req.originalUrl.startsWith(path));
|
|
122
155
|
if (!shouldSkipLogging) {
|
|
123
156
|
this.logRequest(req, requestId, tenantId);
|
|
124
|
-
|
|
125
|
-
let responseLogged = false;
|
|
126
|
-
// Capture response using multiple hooks to ensure we catch it
|
|
127
|
-
const originalSend = res.send;
|
|
128
|
-
const originalJson = res.json;
|
|
129
|
-
const originalEnd = res.end;
|
|
130
|
-
// Store reference to this for use in callbacks
|
|
131
|
-
const self = this;
|
|
132
|
-
// Override res.send
|
|
133
|
-
res.send = function(body) {
|
|
134
|
-
if (!responseLogged) {
|
|
135
|
-
responseLogged = true;
|
|
136
|
-
self.logResponse(req, res, startTime, body, requestId, tenantId);
|
|
137
|
-
}
|
|
138
|
-
return originalSend.call(this, body);
|
|
139
|
-
};
|
|
140
|
-
// Override res.json
|
|
141
|
-
res.json = function(body) {
|
|
142
|
-
if (!responseLogged) {
|
|
143
|
-
responseLogged = true;
|
|
144
|
-
self.logResponse(req, res, startTime, body, requestId, tenantId);
|
|
145
|
-
}
|
|
146
|
-
return originalJson.call(this, body);
|
|
147
|
-
};
|
|
148
|
-
// Override res.end as fallback
|
|
149
|
-
res.end = function(...args) {
|
|
150
|
-
if (!responseLogged) {
|
|
151
|
-
responseLogged = true;
|
|
152
|
-
self.logResponse(req, res, startTime, args[0], requestId, tenantId);
|
|
153
|
-
}
|
|
154
|
-
return originalEnd.apply(this, args);
|
|
155
|
-
};
|
|
156
|
-
// Handle errors
|
|
157
|
-
res.on('error', (error)=>{
|
|
158
|
-
this.logger.error('Response error', {
|
|
159
|
-
context: 'HTTP',
|
|
160
|
-
requestId,
|
|
161
|
-
tenantId,
|
|
162
|
-
method: req.method,
|
|
163
|
-
url: req.originalUrl,
|
|
164
|
-
path: req.path,
|
|
165
|
-
error: error.message,
|
|
166
|
-
stack: error.stack
|
|
167
|
-
});
|
|
168
|
-
});
|
|
157
|
+
this.setupResponseLogging(req, res, startTime, requestId, tenantId);
|
|
169
158
|
}
|
|
170
159
|
next();
|
|
171
160
|
});
|
|
172
161
|
}
|
|
162
|
+
setupResponseLogging(req, res, startTime, requestId, tenantId) {
|
|
163
|
+
let responseLogged = false;
|
|
164
|
+
const originalSend = res.send;
|
|
165
|
+
const originalJson = res.json;
|
|
166
|
+
const originalEnd = res.end;
|
|
167
|
+
const self = this;
|
|
168
|
+
const logOnce = (body)=>{
|
|
169
|
+
if (!responseLogged) {
|
|
170
|
+
responseLogged = true;
|
|
171
|
+
self.logResponse(req, res, startTime, body, requestId, tenantId);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
res.send = function(body) {
|
|
175
|
+
logOnce(body);
|
|
176
|
+
return originalSend.call(this, body);
|
|
177
|
+
};
|
|
178
|
+
res.json = function(body) {
|
|
179
|
+
logOnce(body);
|
|
180
|
+
return originalJson.call(this, body);
|
|
181
|
+
};
|
|
182
|
+
res.end = function(...args) {
|
|
183
|
+
logOnce(args[0]);
|
|
184
|
+
return originalEnd.apply(this, args);
|
|
185
|
+
};
|
|
186
|
+
res.on('error', (error)=>{
|
|
187
|
+
this.logger.error('Response error', {
|
|
188
|
+
...this.buildBaseLogData(req, requestId, tenantId),
|
|
189
|
+
error: error.message,
|
|
190
|
+
stack: error.stack
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
}
|
|
173
194
|
logRequest(req, requestId, tenantId) {
|
|
195
|
+
const ip = getClientIp(req);
|
|
196
|
+
const contentType = req.headers['content-type'] || 'none';
|
|
197
|
+
// Build descriptive message like: Started processing request "POST" "/api/users" from "192.168.1.1"
|
|
198
|
+
const message = `Started processing request "${req.method}" "${req.originalUrl}" from "${ip}"`;
|
|
174
199
|
const logData = {
|
|
175
|
-
|
|
176
|
-
requestId,
|
|
177
|
-
tenantId,
|
|
178
|
-
method: req.method,
|
|
179
|
-
url: req.originalUrl,
|
|
180
|
-
path: req.path,
|
|
200
|
+
...this.buildBaseLogData(req, requestId, tenantId),
|
|
181
201
|
query: Object.keys(req.query).length > 0 ? req.query : undefined,
|
|
182
|
-
ip
|
|
202
|
+
ip,
|
|
183
203
|
userAgent: req.headers['user-agent'],
|
|
184
|
-
contentType
|
|
204
|
+
contentType,
|
|
185
205
|
contentLength: req.headers['content-length']
|
|
186
206
|
};
|
|
187
|
-
// Add debug details if enabled
|
|
188
207
|
if (IS_DEBUG) {
|
|
189
|
-
logData.
|
|
190
|
-
logData.body = truncateBody(req.body);
|
|
191
|
-
logData.params = Object.keys(req.params).length > 0 ? req.params : undefined;
|
|
208
|
+
logData.body = summarizeRequestBody(req.body);
|
|
192
209
|
}
|
|
193
|
-
this.logger.info(
|
|
210
|
+
this.logger.info(message, logData);
|
|
194
211
|
}
|
|
195
212
|
logResponse(req, res, startTime, body, requestId, tenantId) {
|
|
196
213
|
const duration = Date.now() - startTime;
|
|
197
214
|
const statusCode = res.statusCode;
|
|
198
215
|
const level = statusCode >= 500 ? 'error' : statusCode >= 400 ? 'warn' : 'info';
|
|
216
|
+
const userId = getUserId();
|
|
217
|
+
const companyId = getCompanyId();
|
|
218
|
+
const contentType = res.getHeader('content-type') || 'none';
|
|
219
|
+
const contentLength = res.getHeader('content-length') || 'null';
|
|
220
|
+
// Build descriptive message like: Request finished "HTTP/1.1" "POST" "/api/users" - 200 "application/json" 534.29ms
|
|
221
|
+
const message = `Request finished "HTTP/1.1" "${req.method}" "${req.originalUrl}" - ${statusCode} ${contentLength} "${contentType}" ${duration.toFixed(2)}ms`;
|
|
199
222
|
const logData = {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
method: req.method,
|
|
204
|
-
url: req.originalUrl,
|
|
205
|
-
path: req.path,
|
|
223
|
+
...this.buildBaseLogData(req, requestId, tenantId),
|
|
224
|
+
userId,
|
|
225
|
+
companyId,
|
|
206
226
|
statusCode,
|
|
207
227
|
statusMessage: res.statusMessage,
|
|
208
228
|
duration: `${duration}ms`,
|
|
209
229
|
durationMs: duration,
|
|
210
|
-
contentType
|
|
211
|
-
contentLength
|
|
230
|
+
contentType,
|
|
231
|
+
contentLength
|
|
212
232
|
};
|
|
213
|
-
// Add user context if available
|
|
214
|
-
const userId = getUserId();
|
|
215
|
-
const companyId = getCompanyId();
|
|
216
|
-
if (userId) logData.userId = userId;
|
|
217
|
-
if (companyId) logData.companyId = companyId;
|
|
218
|
-
// Add response body for errors or debug mode
|
|
219
233
|
if (statusCode >= 400 || IS_DEBUG) {
|
|
220
|
-
logData.responseBody =
|
|
234
|
+
logData.responseBody = summarizeResponseBody(body);
|
|
221
235
|
}
|
|
222
|
-
this.logger.log(level,
|
|
223
|
-
// Log slow requests separately
|
|
236
|
+
this.logger.log(level, message, logData);
|
|
224
237
|
if (duration > 3000 && statusCode < 400) {
|
|
225
|
-
this.logger.warn(
|
|
226
|
-
|
|
227
|
-
requestId,
|
|
228
|
-
tenantId,
|
|
238
|
+
this.logger.warn(`Slow request detected: "${req.method}" "${req.originalUrl}" took ${duration}ms (threshold: 3000ms)`, {
|
|
239
|
+
...this.buildBaseLogData(req, requestId, tenantId),
|
|
229
240
|
userId,
|
|
230
241
|
companyId,
|
|
231
|
-
method: req.method,
|
|
232
|
-
url: req.originalUrl,
|
|
233
|
-
path: req.path,
|
|
234
242
|
duration: `${duration}ms`,
|
|
235
243
|
durationMs: duration,
|
|
236
244
|
threshold: '3000ms'
|
|
237
245
|
});
|
|
238
246
|
}
|
|
239
247
|
}
|
|
248
|
+
buildBaseLogData(req, requestId, tenantId) {
|
|
249
|
+
return {
|
|
250
|
+
context: 'HTTP',
|
|
251
|
+
requestId,
|
|
252
|
+
tenantId,
|
|
253
|
+
method: req.method,
|
|
254
|
+
url: req.originalUrl,
|
|
255
|
+
path: req.path
|
|
256
|
+
};
|
|
257
|
+
}
|
|
240
258
|
constructor(){
|
|
241
259
|
_define_property(this, "logger", _winstonloggerclass.instance);
|
|
242
260
|
}
|
|
@@ -8,8 +8,8 @@ Object.defineProperty(exports, "CacheModule", {
|
|
|
8
8
|
return CacheModule;
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
|
-
const
|
|
12
|
-
const _constants = require("
|
|
11
|
+
const _hybridcacheclass = require("../../classes/hybrid-cache.class");
|
|
12
|
+
const _constants = require("../../constants");
|
|
13
13
|
const _common = require("@nestjs/common");
|
|
14
14
|
function _ts_decorate(decorators, target, key, desc) {
|
|
15
15
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
@@ -25,7 +25,7 @@ let CacheModule = class CacheModule {
|
|
|
25
25
|
providers: [
|
|
26
26
|
{
|
|
27
27
|
provide: _constants.CACHE_INSTANCE,
|
|
28
|
-
useFactory: ()=>new
|
|
28
|
+
useFactory: ()=>new _hybridcacheclass.HybridCache(memoryTtl, memorySize)
|
|
29
29
|
}
|
|
30
30
|
],
|
|
31
31
|
exports: [
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
_export_star(require("./datasource.module"), exports);
|
|
6
5
|
_export_star(require("./multi-tenant-datasource.service"), exports);
|
|
7
6
|
function _export_star(from, to) {
|
|
8
7
|
Object.keys(from).forEach(function(k) {
|