@eventista/ticketing-common 1.0.1029 → 1.0.1032-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/exception/exception.filter.d.ts +3 -0
  2. package/dist/exception/exception.filter.js +59 -0
  3. package/dist/exception/exception.filter.js.map +1 -1
  4. package/dist/exception/unified-exception.filter.d.ts +9 -0
  5. package/dist/exception/unified-exception.filter.js +152 -0
  6. package/dist/exception/unified-exception.filter.js.map +1 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/logger/custom.logger.d.ts +5 -1
  11. package/dist/logger/custom.logger.js +27 -0
  12. package/dist/logger/custom.logger.js.map +1 -1
  13. package/dist/logger/examples/logger-sentry.example.d.ts +32 -0
  14. package/dist/logger/examples/logger-sentry.example.js +211 -0
  15. package/dist/logger/examples/logger-sentry.example.js.map +1 -0
  16. package/dist/schemas/order/order.interfaces.d.ts +1 -0
  17. package/dist/schemas/order/order.schema.d.ts +1 -0
  18. package/dist/schemas/order/order.schema.js +4 -0
  19. package/dist/schemas/order/order.schema.js.map +1 -1
  20. package/dist/sentry/decorators/index.d.ts +2 -0
  21. package/dist/sentry/decorators/index.js +19 -0
  22. package/dist/sentry/decorators/index.js.map +1 -0
  23. package/dist/sentry/decorators/sentry-capture.decorator.d.ts +9 -0
  24. package/dist/sentry/decorators/sentry-capture.decorator.js +13 -0
  25. package/dist/sentry/decorators/sentry-capture.decorator.js.map +1 -0
  26. package/dist/sentry/decorators/sentry-trace.decorator.d.ts +9 -0
  27. package/dist/sentry/decorators/sentry-trace.decorator.js +8 -0
  28. package/dist/sentry/decorators/sentry-trace.decorator.js.map +1 -0
  29. package/dist/sentry/examples/optimized-usage.example.d.ts +33 -0
  30. package/dist/sentry/examples/optimized-usage.example.js +300 -0
  31. package/dist/sentry/examples/optimized-usage.example.js.map +1 -0
  32. package/dist/sentry/examples/sentry-usage.example.d.ts +39 -0
  33. package/dist/sentry/examples/sentry-usage.example.js +262 -0
  34. package/dist/sentry/examples/sentry-usage.example.js.map +1 -0
  35. package/dist/sentry/index.d.ts +10 -0
  36. package/dist/sentry/index.js +27 -0
  37. package/dist/sentry/index.js.map +1 -0
  38. package/dist/sentry/interceptors/index.d.ts +2 -0
  39. package/dist/sentry/interceptors/index.js +19 -0
  40. package/dist/sentry/interceptors/index.js.map +1 -0
  41. package/dist/sentry/interceptors/sentry-capture.interceptor.d.ts +8 -0
  42. package/dist/sentry/interceptors/sentry-capture.interceptor.js +80 -0
  43. package/dist/sentry/interceptors/sentry-capture.interceptor.js.map +1 -0
  44. package/dist/sentry/interceptors/sentry-trace.interceptor.d.ts +8 -0
  45. package/dist/sentry/interceptors/sentry-trace.interceptor.js +56 -0
  46. package/dist/sentry/interceptors/sentry-trace.interceptor.js.map +1 -0
  47. package/dist/sentry/sentry-logger.helper.d.ts +22 -0
  48. package/dist/sentry/sentry-logger.helper.js +153 -0
  49. package/dist/sentry/sentry-logger.helper.js.map +1 -0
  50. package/dist/sentry/sentry-safe.module.d.ts +11 -0
  51. package/dist/sentry/sentry-safe.module.js +82 -0
  52. package/dist/sentry/sentry-safe.module.js.map +1 -0
  53. package/dist/sentry/sentry.advanced-config.d.ts +35 -0
  54. package/dist/sentry/sentry.advanced-config.js +99 -0
  55. package/dist/sentry/sentry.advanced-config.js.map +1 -0
  56. package/dist/sentry/sentry.config.d.ts +20 -0
  57. package/dist/sentry/sentry.config.js +20 -0
  58. package/dist/sentry/sentry.config.js.map +1 -0
  59. package/dist/sentry/sentry.filter.d.ts +12 -0
  60. package/dist/sentry/sentry.filter.js +139 -0
  61. package/dist/sentry/sentry.filter.js.map +1 -0
  62. package/dist/sentry/sentry.interceptor.d.ts +9 -0
  63. package/dist/sentry/sentry.interceptor.js +80 -0
  64. package/dist/sentry/sentry.interceptor.js.map +1 -0
  65. package/dist/sentry/sentry.module.d.ts +2 -0
  66. package/dist/sentry/sentry.module.js +45 -0
  67. package/dist/sentry/sentry.module.js.map +1 -0
  68. package/dist/sentry/sentry.service.d.ts +56 -0
  69. package/dist/sentry/sentry.service.js +255 -0
  70. package/dist/sentry/sentry.service.js.map +1 -0
  71. package/dist/sentry/types/index.d.ts +30 -0
  72. package/dist/sentry/types/index.js +3 -0
  73. package/dist/sentry/types/index.js.map +1 -0
  74. package/dist/shared.module.js +3 -0
  75. package/dist/shared.module.js.map +1 -1
  76. package/dist/tsconfig.tsbuildinfo +1 -1
  77. package/package.json +10 -2
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SentryLoggerHelper = void 0;
4
+ const Sentry = require("@sentry/nestjs");
5
+ class SentryLoggerHelper {
6
+ static captureMessage(message, level, context, metadata, options = { enabled: true }) {
7
+ if (!options.enabled) {
8
+ return;
9
+ }
10
+ if (!this.checkRateLimit(message, options.rateLimitPerMinute)) {
11
+ return;
12
+ }
13
+ if (this.shouldExclude(message, options.excludePatterns)) {
14
+ return;
15
+ }
16
+ try {
17
+ Sentry.withScope((scope) => {
18
+ if (context) {
19
+ scope.setTag('logger.context', context);
20
+ }
21
+ scope.setLevel(level);
22
+ if (metadata) {
23
+ const sanitizedMetadata = this.sanitizeMetadata(metadata, options.sensitiveFields);
24
+ scope.setContext('logger.metadata', {
25
+ data: sanitizedMetadata,
26
+ timestamp: new Date().toISOString(),
27
+ });
28
+ }
29
+ Sentry.addBreadcrumb({
30
+ message: `Logger ${level}: ${message}`,
31
+ category: 'logger',
32
+ level: level === 'error' ? 'error' : level === 'warning' ? 'warning' : 'info',
33
+ data: {
34
+ context,
35
+ hasMetadata: !!metadata,
36
+ },
37
+ });
38
+ Sentry.captureMessage(message, level);
39
+ });
40
+ }
41
+ catch (error) {
42
+ console.error('Failed to capture message to Sentry:', error);
43
+ }
44
+ }
45
+ static captureException(exception, message, context, options = { enabled: true }) {
46
+ if (!options.enabled) {
47
+ return;
48
+ }
49
+ try {
50
+ Sentry.withScope((scope) => {
51
+ if (context) {
52
+ scope.setTag('logger.context', context);
53
+ }
54
+ scope.setLevel('error');
55
+ scope.setContext('logger.exception', {
56
+ message: exception.message,
57
+ name: exception.name,
58
+ stack: exception.stack,
59
+ logMessage: message,
60
+ timestamp: new Date().toISOString(),
61
+ });
62
+ Sentry.addBreadcrumb({
63
+ message: `Logger exception: ${message}`,
64
+ category: 'logger',
65
+ level: 'error',
66
+ data: {
67
+ context,
68
+ exceptionName: exception.name,
69
+ exceptionMessage: exception.message,
70
+ },
71
+ });
72
+ Sentry.captureException(exception);
73
+ });
74
+ }
75
+ catch (error) {
76
+ console.error('Failed to capture exception to Sentry:', error);
77
+ }
78
+ }
79
+ static checkRateLimit(message, customLimit) {
80
+ const limit = customLimit || this.DEFAULT_RATE_LIMIT;
81
+ const now = Date.now();
82
+ const messageKey = this.getMessageKey(message);
83
+ const record = this.messageCount.get(messageKey);
84
+ if (!record) {
85
+ this.messageCount.set(messageKey, { count: 1, lastReset: now });
86
+ return true;
87
+ }
88
+ if (now - record.lastReset > this.RATE_LIMIT_WINDOW) {
89
+ record.count = 1;
90
+ record.lastReset = now;
91
+ return true;
92
+ }
93
+ if (record.count < limit) {
94
+ record.count++;
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ static shouldExclude(message, excludePatterns) {
100
+ if (!excludePatterns || excludePatterns.length === 0) {
101
+ return false;
102
+ }
103
+ return excludePatterns.some(pattern => pattern.test(message));
104
+ }
105
+ static sanitizeMetadata(metadata, sensitiveFields) {
106
+ if (!metadata || typeof metadata !== 'object') {
107
+ return metadata;
108
+ }
109
+ const defaultSensitiveFields = [
110
+ 'password', 'token', 'authorization', 'secret', 'key', 'credential',
111
+ 'apiKey', 'accessToken', 'refreshToken', 'sessionId', 'cookie'
112
+ ];
113
+ const fieldsToSanitize = [...defaultSensitiveFields, ...(sensitiveFields || [])];
114
+ const sanitized = JSON.parse(JSON.stringify(metadata));
115
+ const sanitizeObject = (obj) => {
116
+ if (Array.isArray(obj)) {
117
+ return obj.map(sanitizeObject);
118
+ }
119
+ if (obj && typeof obj === 'object') {
120
+ const result = {};
121
+ for (const [key, value] of Object.entries(obj)) {
122
+ if (fieldsToSanitize.some(field => key.toLowerCase().includes(field.toLowerCase()))) {
123
+ result[key] = '[REDACTED]';
124
+ }
125
+ else {
126
+ result[key] = sanitizeObject(value);
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+ return obj;
132
+ };
133
+ return sanitizeObject(sanitized);
134
+ }
135
+ static getMessageKey(message) {
136
+ return message.substring(0, 50);
137
+ }
138
+ static clearRateLimitCache() {
139
+ this.messageCount.clear();
140
+ }
141
+ static getRateLimitStats() {
142
+ const stats = {};
143
+ this.messageCount.forEach((value, key) => {
144
+ stats[key] = { ...value };
145
+ });
146
+ return stats;
147
+ }
148
+ }
149
+ exports.SentryLoggerHelper = SentryLoggerHelper;
150
+ SentryLoggerHelper.messageCount = new Map();
151
+ SentryLoggerHelper.DEFAULT_RATE_LIMIT = 60;
152
+ SentryLoggerHelper.RATE_LIMIT_WINDOW = 60 * 1000;
153
+ //# sourceMappingURL=sentry-logger.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry-logger.helper.js","sourceRoot":"","sources":["../../src/sentry/sentry-logger.helper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ export interface SentryModuleOptions {
3
+ useUnifiedFilter?: boolean;
4
+ enableInterceptors?: boolean;
5
+ enableExceptionFilter?: boolean;
6
+ }
7
+ export declare class SentrySafeModule {
8
+ static forRoot(options?: SentryModuleOptions): DynamicModule;
9
+ static forBasic(): DynamicModule;
10
+ static forFull(): DynamicModule;
11
+ }
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var SentrySafeModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.SentrySafeModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const config_1 = require("@nestjs/config");
13
+ const core_1 = require("@nestjs/core");
14
+ const sentry_service_1 = require("./sentry.service");
15
+ const sentry_interceptor_1 = require("./sentry.interceptor");
16
+ const sentry_filter_1 = require("./sentry.filter");
17
+ const sentry_trace_interceptor_1 = require("./interceptors/sentry-trace.interceptor");
18
+ const sentry_capture_interceptor_1 = require("./interceptors/sentry-capture.interceptor");
19
+ const unified_exception_filter_1 = require("../exception/unified-exception.filter");
20
+ const sentry_config_1 = require("./sentry.config");
21
+ let SentrySafeModule = SentrySafeModule_1 = class SentrySafeModule {
22
+ static forRoot(options = {}) {
23
+ const { useUnifiedFilter = true, enableInterceptors = true, enableExceptionFilter = false, } = options;
24
+ const providers = [
25
+ sentry_service_1.SentryService,
26
+ ];
27
+ if (enableInterceptors) {
28
+ providers.push({
29
+ provide: core_1.APP_INTERCEPTOR,
30
+ useClass: sentry_interceptor_1.SentryInterceptor,
31
+ }, {
32
+ provide: core_1.APP_INTERCEPTOR,
33
+ useClass: sentry_trace_interceptor_1.SentryTraceInterceptor,
34
+ }, {
35
+ provide: core_1.APP_INTERCEPTOR,
36
+ useClass: sentry_capture_interceptor_1.SentryCaptureInterceptor,
37
+ });
38
+ }
39
+ if (enableExceptionFilter) {
40
+ if (useUnifiedFilter) {
41
+ providers.push({
42
+ provide: core_1.APP_FILTER,
43
+ useClass: unified_exception_filter_1.UnifiedExceptionFilter,
44
+ });
45
+ }
46
+ else {
47
+ providers.push({
48
+ provide: core_1.APP_FILTER,
49
+ useClass: sentry_filter_1.SentryExceptionFilter,
50
+ });
51
+ }
52
+ }
53
+ return {
54
+ module: SentrySafeModule_1,
55
+ imports: [
56
+ config_1.ConfigModule.forFeature(sentry_config_1.default),
57
+ ],
58
+ providers,
59
+ exports: [sentry_service_1.SentryService],
60
+ };
61
+ }
62
+ static forBasic() {
63
+ return this.forRoot({
64
+ useUnifiedFilter: false,
65
+ enableInterceptors: true,
66
+ enableExceptionFilter: false,
67
+ });
68
+ }
69
+ static forFull() {
70
+ return this.forRoot({
71
+ useUnifiedFilter: true,
72
+ enableInterceptors: true,
73
+ enableExceptionFilter: true,
74
+ });
75
+ }
76
+ };
77
+ exports.SentrySafeModule = SentrySafeModule;
78
+ exports.SentrySafeModule = SentrySafeModule = SentrySafeModule_1 = __decorate([
79
+ (0, common_1.Global)(),
80
+ (0, common_1.Module)({})
81
+ ], SentrySafeModule);
82
+ //# sourceMappingURL=sentry-safe.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry-safe.module.js","sourceRoot":"","sources":["../../src/sentry/sentry-safe.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+D;AAC/D,2CAA8C;AAC9C,uCAA2D;AAC3D,qDAAiD;AACjD,6DAAyD;AACzD,mDAAwD;AACxD,sFAAiF;AACjF,0FAAqF;AACrF,oFAA+E;AAC/E,mDAA2C;AAUpC,IAAM,gBAAgB,wBAAtB,MAAM,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,UAA+B,EAAE;QAC9C,MAAM,EACJ,gBAAgB,GAAG,IAAI,EACvB,kBAAkB,GAAG,IAAI,EACzB,qBAAqB,GAAG,KAAK,GAC9B,GAAG,OAAO,CAAC;QAEZ,MAAM,SAAS,GAAU;YACvB,8BAAa;SACd,CAAC;QAGF,IAAI,kBAAkB,EAAE,CAAC;YACvB,SAAS,CAAC,IAAI,CACZ;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,sCAAiB;aAC5B,EACD;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,iDAAsB;aACjC,EACD;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,qDAAwB;aACnC,CACF,CAAC;QACJ,CAAC;QAGD,IAAI,qBAAqB,EAAE,CAAC;YAC1B,IAAI,gBAAgB,EAAE,CAAC;gBACrB,SAAS,CAAC,IAAI,CAAC;oBACb,OAAO,EAAE,iBAAU;oBACnB,QAAQ,EAAE,iDAAsB;iBACjC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CAAC;oBACb,OAAO,EAAE,iBAAU;oBACnB,QAAQ,EAAE,qCAAqB;iBAChC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO;YACL,MAAM,EAAE,kBAAgB;YACxB,OAAO,EAAE;gBACP,qBAAY,CAAC,UAAU,CAAC,uBAAY,CAAC;aACtC;YACD,SAAS;YACT,OAAO,EAAE,CAAC,8BAAa,CAAC;SACzB,CAAC;IACJ,CAAC;IAGD,MAAM,CAAC,QAAQ;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,gBAAgB,EAAE,KAAK;YACvB,kBAAkB,EAAE,IAAI;YACxB,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAC;IACL,CAAC;IAGD,MAAM,CAAC,OAAO;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC;YAClB,gBAAgB,EAAE,IAAI;YACtB,kBAAkB,EAAE,IAAI;YACxB,qBAAqB,EAAE,IAAI;SAC5B,CAAC,CAAC;IACL,CAAC;CACF,CAAA;AAxEY,4CAAgB;2BAAhB,gBAAgB;IAF5B,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,gBAAgB,CAwE5B"}
@@ -0,0 +1,35 @@
1
+ import { SentryConfig } from './sentry.config';
2
+ export interface AdvancedSentryConfig extends SentryConfig {
3
+ logger: {
4
+ enabled: boolean;
5
+ rateLimitPerMinute: number;
6
+ excludePatterns: string[];
7
+ sensitiveFields: string[];
8
+ captureConsoleErrors: boolean;
9
+ };
10
+ performance: {
11
+ enableProfiling: boolean;
12
+ maxSpanDuration: number;
13
+ ignoreTransactions: string[];
14
+ customSamplingRules: Array<{
15
+ pattern: string;
16
+ sampleRate: number;
17
+ }>;
18
+ };
19
+ errorFiltering: {
20
+ ignoreErrors: string[];
21
+ ignoreUrls: string[];
22
+ denyUrls: string[];
23
+ beforeSendFilters: string[];
24
+ };
25
+ context: {
26
+ captureRequestBody: boolean;
27
+ captureResponseBody: boolean;
28
+ maxRequestBodySize: number;
29
+ maxResponseBodySize: number;
30
+ captureHeaders: boolean;
31
+ sensitiveHeaders: string[];
32
+ };
33
+ }
34
+ declare const _default: (() => AdvancedSentryConfig) & import("@nestjs/config").ConfigFactoryKeyHost<AdvancedSentryConfig>;
35
+ export default _default;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("@nestjs/config");
4
+ exports.default = (0, config_1.registerAs)('sentryAdvanced', () => ({
5
+ dsn: process.env.SENTRY_DSN || '',
6
+ environment: process.env.NODE_ENV || 'development',
7
+ release: process.env.SENTRY_RELEASE || process.env.npm_package_version,
8
+ debug: process.env.SENTRY_DEBUG?.toLowerCase() === 'true',
9
+ tracesSampleRate: parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE || '0.1'),
10
+ profilesSampleRate: parseFloat(process.env.SENTRY_PROFILES_SAMPLE_RATE || '0.1'),
11
+ enabled: process.env.SENTRY_ENABLED?.toLowerCase() !== 'false' && !!process.env.SENTRY_DSN,
12
+ integrations: {
13
+ http: process.env.SENTRY_HTTP_INTEGRATION?.toLowerCase() !== 'false',
14
+ express: process.env.SENTRY_EXPRESS_INTEGRATION?.toLowerCase() !== 'false',
15
+ graphql: process.env.SENTRY_GRAPHQL_INTEGRATION?.toLowerCase() !== 'false',
16
+ mongo: process.env.SENTRY_MONGO_INTEGRATION?.toLowerCase() !== 'false',
17
+ redis: process.env.SENTRY_REDIS_INTEGRATION?.toLowerCase() !== 'false',
18
+ },
19
+ logger: {
20
+ enabled: process.env.SENTRY_LOGGER_ENABLED?.toLowerCase() !== 'false',
21
+ rateLimitPerMinute: parseInt(process.env.SENTRY_LOGGER_RATE_LIMIT || '30', 10),
22
+ excludePatterns: process.env.SENTRY_LOGGER_EXCLUDE_PATTERNS?.split(',') || [
23
+ 'health.*check',
24
+ 'ping',
25
+ 'connection.*established',
26
+ 'server.*started'
27
+ ],
28
+ sensitiveFields: process.env.SENTRY_LOGGER_SENSITIVE_FIELDS?.split(',') || [
29
+ 'password',
30
+ 'token',
31
+ 'secret',
32
+ 'key',
33
+ 'credential',
34
+ 'authorization',
35
+ 'cookie'
36
+ ],
37
+ captureConsoleErrors: process.env.SENTRY_CAPTURE_CONSOLE_ERRORS?.toLowerCase() === 'true',
38
+ },
39
+ performance: {
40
+ enableProfiling: process.env.SENTRY_ENABLE_PROFILING?.toLowerCase() === 'true',
41
+ maxSpanDuration: parseInt(process.env.SENTRY_MAX_SPAN_DURATION || '30000', 10),
42
+ ignoreTransactions: process.env.SENTRY_IGNORE_TRANSACTIONS?.split(',') || [
43
+ '/health',
44
+ '/metrics',
45
+ '/ping',
46
+ '/favicon.ico'
47
+ ],
48
+ customSamplingRules: [
49
+ {
50
+ pattern: '/api/health',
51
+ sampleRate: 0.01,
52
+ },
53
+ {
54
+ pattern: '/api/users',
55
+ sampleRate: 0.5,
56
+ }
57
+ ],
58
+ },
59
+ errorFiltering: {
60
+ ignoreErrors: process.env.SENTRY_IGNORE_ERRORS?.split(',') || [
61
+ 'ValidationError',
62
+ 'BadRequestException',
63
+ 'UnauthorizedException',
64
+ 'ForbiddenException',
65
+ 'NotFoundException',
66
+ 'ConflictException',
67
+ 'Network Error',
68
+ 'timeout',
69
+ 'AbortError'
70
+ ],
71
+ ignoreUrls: process.env.SENTRY_IGNORE_URLS?.split(',') || [
72
+ '/health',
73
+ '/metrics',
74
+ '/ping'
75
+ ],
76
+ denyUrls: process.env.SENTRY_DENY_URLS?.split(',') || [],
77
+ beforeSendFilters: process.env.SENTRY_BEFORE_SEND_FILTERS?.split(',') || [
78
+ 'removePasswords',
79
+ 'removeTokens',
80
+ 'removePII'
81
+ ],
82
+ },
83
+ context: {
84
+ captureRequestBody: process.env.SENTRY_CAPTURE_REQUEST_BODY?.toLowerCase() === 'true',
85
+ captureResponseBody: process.env.SENTRY_CAPTURE_RESPONSE_BODY?.toLowerCase() === 'true',
86
+ maxRequestBodySize: parseInt(process.env.SENTRY_MAX_REQUEST_BODY_SIZE || '10240', 10),
87
+ maxResponseBodySize: parseInt(process.env.SENTRY_MAX_RESPONSE_BODY_SIZE || '10240', 10),
88
+ captureHeaders: process.env.SENTRY_CAPTURE_HEADERS?.toLowerCase() !== 'false',
89
+ sensitiveHeaders: process.env.SENTRY_SENSITIVE_HEADERS?.split(',') || [
90
+ 'authorization',
91
+ 'cookie',
92
+ 'x-api-key',
93
+ 'x-auth-token',
94
+ 'x-access-token',
95
+ 'x-refresh-token'
96
+ ],
97
+ },
98
+ }));
99
+ //# sourceMappingURL=sentry.advanced-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.advanced-config.js","sourceRoot":"","sources":["../../src/sentry/sentry.advanced-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ export interface SentryConfig {
2
+ dsn: string;
3
+ environment: string;
4
+ release?: string;
5
+ debug: boolean;
6
+ tracesSampleRate: number;
7
+ profilesSampleRate: number;
8
+ enabled: boolean;
9
+ integrations?: {
10
+ http: boolean;
11
+ express: boolean;
12
+ graphql: boolean;
13
+ mongo: boolean;
14
+ redis: boolean;
15
+ };
16
+ beforeSend?: (event: any) => any;
17
+ beforeSendTransaction?: (event: any) => any;
18
+ }
19
+ declare const _default: (() => SentryConfig) & import("@nestjs/config").ConfigFactoryKeyHost<SentryConfig>;
20
+ export default _default;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("@nestjs/config");
4
+ exports.default = (0, config_1.registerAs)('sentry', () => ({
5
+ dsn: process.env.SENTRY_DSN || '',
6
+ environment: process.env.NODE_ENV || 'development',
7
+ release: process.env.SENTRY_RELEASE || process.env.npm_package_version,
8
+ debug: process.env.SENTRY_DEBUG?.toLowerCase() === 'true',
9
+ tracesSampleRate: parseFloat(process.env.SENTRY_TRACES_SAMPLE_RATE || '0.1'),
10
+ profilesSampleRate: parseFloat(process.env.SENTRY_PROFILES_SAMPLE_RATE || '0.1'),
11
+ enabled: process.env.SENTRY_ENABLED?.toLowerCase() !== 'false' && !!process.env.SENTRY_DSN,
12
+ integrations: {
13
+ http: process.env.SENTRY_HTTP_INTEGRATION?.toLowerCase() !== 'false',
14
+ express: process.env.SENTRY_EXPRESS_INTEGRATION?.toLowerCase() !== 'false',
15
+ graphql: process.env.SENTRY_GRAPHQL_INTEGRATION?.toLowerCase() !== 'false',
16
+ mongo: process.env.SENTRY_MONGO_INTEGRATION?.toLowerCase() !== 'false',
17
+ redis: process.env.SENTRY_REDIS_INTEGRATION?.toLowerCase() !== 'false',
18
+ },
19
+ }));
20
+ //# sourceMappingURL=sentry.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.config.js","sourceRoot":"","sources":["../../src/sentry/sentry.config.ts"],"names":[],"mappings":";;AAAA,2CAA4C;AAqB5C,kBAAe,IAAA,mBAAU,EAAC,QAAQ,EAAE,GAAiB,EAAE,CAAC,CAAC;IACvD,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE;IACjC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;IAClD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB;IACtE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,KAAK,MAAM;IACzD,gBAAgB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,KAAK,CAAC;IAC5E,kBAAkB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,KAAK,CAAC;IAChF,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,WAAW,EAAE,KAAK,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU;IAC1F,YAAY,EAAE;QACZ,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,WAAW,EAAE,KAAK,OAAO;QACpE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,WAAW,EAAE,KAAK,OAAO;QAC1E,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,WAAW,EAAE,KAAK,OAAO;QAC1E,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,EAAE,KAAK,OAAO;QACtE,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,WAAW,EAAE,KAAK,OAAO;KACvE;CACF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { ArgumentsHost, ExceptionFilter } from '@nestjs/common';
2
+ import { SentryService } from './sentry.service';
3
+ export declare class SentryExceptionFilter implements ExceptionFilter {
4
+ private readonly sentryService;
5
+ private readonly logger;
6
+ constructor(sentryService: SentryService);
7
+ catch(exception: any, host: ArgumentsHost): void;
8
+ private getErrorMessage;
9
+ private logError;
10
+ private sanitizeHeaders;
11
+ private sanitizeBody;
12
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var SentryExceptionFilter_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.SentryExceptionFilter = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const sentry_service_1 = require("./sentry.service");
16
+ const custom_logger_1 = require("../logger/custom.logger");
17
+ let SentryExceptionFilter = SentryExceptionFilter_1 = class SentryExceptionFilter {
18
+ constructor(sentryService) {
19
+ this.sentryService = sentryService;
20
+ this.logger = new custom_logger_1.CustomLogger(SentryExceptionFilter_1.name);
21
+ }
22
+ catch(exception, host) {
23
+ const ctx = host.switchToHttp();
24
+ const response = ctx.getResponse();
25
+ const request = ctx.getRequest();
26
+ const status = exception instanceof common_1.HttpException
27
+ ? exception.getStatus()
28
+ : common_1.HttpStatus.INTERNAL_SERVER_ERROR;
29
+ if (status >= 500 || !(exception instanceof common_1.HttpException)) {
30
+ this.sentryService.withScope((scope) => {
31
+ scope.setTag('http.status_code', status);
32
+ scope.setTag('http.method', request.method);
33
+ scope.setTag('http.url', request.url);
34
+ scope.setContext('request', {
35
+ method: request.method,
36
+ url: request.url,
37
+ headers: this.sanitizeHeaders(request.headers),
38
+ query: request.query,
39
+ body: this.sanitizeBody(request.body),
40
+ params: request.params,
41
+ });
42
+ scope.setContext('response', {
43
+ statusCode: status,
44
+ });
45
+ if (request.user) {
46
+ scope.setUser({
47
+ id: request.user.id || request.user.sub,
48
+ email: request.user.email,
49
+ username: request.user.username,
50
+ });
51
+ }
52
+ this.sentryService.captureException(exception, 'ExceptionFilter');
53
+ });
54
+ }
55
+ this.logError(exception, request, status);
56
+ const errorResponse = {
57
+ statusCode: status,
58
+ errorCode: status,
59
+ message: this.getErrorMessage(exception, status),
60
+ path: request.url,
61
+ timestamp: new Date().toISOString(),
62
+ data: exception instanceof common_1.HttpException ? exception.getResponse()['data'] : null,
63
+ };
64
+ response.status(status).json(errorResponse);
65
+ }
66
+ getErrorMessage(exception, status) {
67
+ if (exception instanceof common_1.HttpException) {
68
+ const response = exception.getResponse();
69
+ if (typeof response === 'string') {
70
+ return response;
71
+ }
72
+ if (typeof response === 'object' && response['message']) {
73
+ return Array.isArray(response['message'])
74
+ ? response['message'].join(', ')
75
+ : response['message'];
76
+ }
77
+ }
78
+ if (status >= 500) {
79
+ return 'Hệ thống đang bận, vui lòng thử lại sau.';
80
+ }
81
+ return exception.message || 'Đã xảy ra lỗi không xác định.';
82
+ }
83
+ logError(exception, request, status) {
84
+ const errorInfo = {
85
+ exception: {
86
+ name: exception.name,
87
+ message: exception.message,
88
+ stack: exception.stack,
89
+ },
90
+ request: {
91
+ method: request.method,
92
+ url: request.url,
93
+ headers: this.sanitizeHeaders(request.headers),
94
+ query: request.query,
95
+ body: this.sanitizeBody(request.body),
96
+ params: request.params,
97
+ },
98
+ response: {
99
+ statusCode: status,
100
+ },
101
+ timestamp: new Date().toISOString(),
102
+ };
103
+ if (status >= 500) {
104
+ this.logger.error(`[${request.method}] ${request.url} - Status: ${status}`, JSON.stringify(errorInfo));
105
+ }
106
+ else {
107
+ this.logger.warn(`[${request.method}] ${request.url} - Status: ${status}`, JSON.stringify(errorInfo));
108
+ }
109
+ }
110
+ sanitizeHeaders(headers) {
111
+ const sensitiveHeaders = ['authorization', 'cookie', 'x-api-key', 'x-auth-token'];
112
+ const sanitized = { ...headers };
113
+ for (const header of sensitiveHeaders) {
114
+ if (header in sanitized) {
115
+ sanitized[header] = '[REDACTED]';
116
+ }
117
+ }
118
+ return sanitized;
119
+ }
120
+ sanitizeBody(body) {
121
+ if (!body || typeof body !== 'object') {
122
+ return body;
123
+ }
124
+ const sensitiveFields = ['password', 'token', 'authorization', 'secret', 'key', 'credential'];
125
+ const sanitized = { ...body };
126
+ for (const field of sensitiveFields) {
127
+ if (field in sanitized) {
128
+ sanitized[field] = '[REDACTED]';
129
+ }
130
+ }
131
+ return sanitized;
132
+ }
133
+ };
134
+ exports.SentryExceptionFilter = SentryExceptionFilter;
135
+ exports.SentryExceptionFilter = SentryExceptionFilter = SentryExceptionFilter_1 = __decorate([
136
+ (0, common_1.Catch)(),
137
+ __metadata("design:paramtypes", [sentry_service_1.SentryService])
138
+ ], SentryExceptionFilter);
139
+ //# sourceMappingURL=sentry.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sentry.filter.js","sourceRoot":"","sources":["../../src/sentry/sentry.filter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ import { SentryService } from './sentry.service';
4
+ export declare class SentryInterceptor implements NestInterceptor {
5
+ private readonly sentryService;
6
+ constructor(sentryService: SentryService);
7
+ intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
8
+ private sanitizeHeaders;
9
+ }