@nest-omni/core 3.1.2-8 → 4.1.2-9

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 (94) hide show
  1. package/audit/audit.module.d.ts +10 -0
  2. package/audit/audit.module.js +231 -0
  3. package/audit/controllers/audit.controller.d.ts +20 -0
  4. package/audit/controllers/audit.controller.js +142 -0
  5. package/audit/controllers/index.d.ts +1 -0
  6. package/audit/controllers/index.js +17 -0
  7. package/audit/decorators/audit-controller.decorator.d.ts +5 -0
  8. package/audit/decorators/audit-controller.decorator.js +17 -0
  9. package/audit/decorators/audit-operation.decorator.d.ts +5 -0
  10. package/audit/decorators/audit-operation.decorator.js +23 -0
  11. package/audit/decorators/entity-audit.decorator.d.ts +5 -0
  12. package/audit/decorators/entity-audit.decorator.js +19 -0
  13. package/audit/decorators/index.d.ts +2 -0
  14. package/audit/decorators/index.js +18 -0
  15. package/audit/dto/audit-log-query.dto.d.ts +14 -0
  16. package/audit/dto/audit-log-query.dto.js +95 -0
  17. package/audit/dto/begin-transaction.dto.d.ts +3 -0
  18. package/audit/dto/begin-transaction.dto.js +22 -0
  19. package/audit/dto/compare-entities.dto.d.ts +6 -0
  20. package/audit/dto/compare-entities.dto.js +44 -0
  21. package/audit/dto/index.d.ts +5 -0
  22. package/audit/dto/index.js +21 -0
  23. package/audit/dto/pre-check-restore.dto.d.ts +5 -0
  24. package/audit/dto/pre-check-restore.dto.js +32 -0
  25. package/audit/dto/restore-entity.dto.d.ts +9 -0
  26. package/audit/dto/restore-entity.dto.js +53 -0
  27. package/audit/entities/entity-audit-log.entity.d.ts +18 -0
  28. package/audit/entities/entity-audit-log.entity.js +81 -0
  29. package/audit/entities/entity-transaction.entity.d.ts +14 -0
  30. package/audit/entities/entity-transaction.entity.js +51 -0
  31. package/audit/entities/index.d.ts +2 -0
  32. package/audit/entities/index.js +18 -0
  33. package/audit/entities/manual-operation-log.entity.d.ts +15 -0
  34. package/audit/entities/manual-operation-log.entity.js +82 -0
  35. package/audit/entities/operation-template.entity.d.ts +11 -0
  36. package/audit/entities/operation-template.entity.js +65 -0
  37. package/audit/enums/audit.enums.d.ts +27 -0
  38. package/audit/enums/audit.enums.js +35 -0
  39. package/audit/enums/index.d.ts +1 -0
  40. package/audit/enums/index.js +17 -0
  41. package/audit/index.d.ts +10 -0
  42. package/audit/index.js +26 -0
  43. package/audit/interceptors/audit.interceptor.d.ts +12 -0
  44. package/audit/interceptors/audit.interceptor.js +95 -0
  45. package/audit/interceptors/index.d.ts +1 -0
  46. package/audit/interceptors/index.js +17 -0
  47. package/audit/interfaces/audit.interfaces.d.ts +119 -0
  48. package/audit/interfaces/audit.interfaces.js +2 -0
  49. package/audit/interfaces/index.d.ts +1 -0
  50. package/audit/interfaces/index.js +17 -0
  51. package/audit/services/audit-context.service.d.ts +10 -0
  52. package/audit/services/audit-context.service.js +55 -0
  53. package/audit/services/audit-strategy.service.d.ts +19 -0
  54. package/audit/services/audit-strategy.service.js +89 -0
  55. package/audit/services/entity-audit.service.d.ts +37 -0
  56. package/audit/services/entity-audit.service.js +484 -0
  57. package/audit/services/index.d.ts +5 -0
  58. package/audit/services/index.js +21 -0
  59. package/audit/services/manual-audit-log.service.d.ts +29 -0
  60. package/audit/services/manual-audit-log.service.js +184 -0
  61. package/audit/services/multi-database.service.d.ts +10 -0
  62. package/audit/services/multi-database.service.js +59 -0
  63. package/audit/services/operation-description.service.d.ts +21 -0
  64. package/audit/services/operation-description.service.js +213 -0
  65. package/audit/services/transaction-audit.service.d.ts +22 -0
  66. package/audit/services/transaction-audit.service.js +201 -0
  67. package/audit/subscribers/entity-audit.subscriber.d.ts +14 -0
  68. package/audit/subscribers/entity-audit.subscriber.js +136 -0
  69. package/audit/subscribers/index.d.ts +1 -0
  70. package/audit/subscribers/index.js +17 -0
  71. package/common/abstract.entity.js +1 -1
  72. package/http-client/examples/advanced-usage.example.js +14 -1
  73. package/http-client/examples/auth-with-waiting-lock.example.d.ts +17 -0
  74. package/http-client/examples/auth-with-waiting-lock.example.js +336 -0
  75. package/http-client/examples/basic-usage.example.d.ts +1 -9
  76. package/http-client/examples/basic-usage.example.js +4 -14
  77. package/http-client/examples/multi-api-configuration.example.js +4 -4
  78. package/http-client/http-client.module.js +7 -4
  79. package/http-client/services/api-client-registry.service.d.ts +2 -1
  80. package/http-client/services/api-client-registry.service.js +2 -1
  81. package/http-client/services/http-client.service.d.ts +18 -1
  82. package/http-client/services/http-client.service.js +123 -3
  83. package/http-client/services/http-log-query.service.d.ts +20 -0
  84. package/http-client/services/http-log-query.service.js +176 -0
  85. package/http-client/services/http-replay.service.d.ts +58 -0
  86. package/http-client/services/http-replay.service.js +266 -0
  87. package/http-client/services/log-cleanup.service.js +2 -2
  88. package/http-client/services/logging.service.js +1 -1
  89. package/http-client/utils/request-id.util.d.ts +4 -0
  90. package/http-client/utils/request-id.util.js +34 -0
  91. package/index.d.ts +1 -0
  92. package/index.js +1 -0
  93. package/package.json +1 -1
  94. package/setup/bootstrap.setup.js +5 -1
@@ -0,0 +1,266 @@
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
12
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
13
+ return new (P || (P = Promise))(function (resolve, reject) {
14
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
15
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
16
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
17
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
18
+ });
19
+ };
20
+ var HttpReplayService_1;
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.HttpReplayService = void 0;
23
+ const common_1 = require("@nestjs/common");
24
+ const http_client_service_1 = require("./http-client.service");
25
+ const http_log_query_service_1 = require("./http-log-query.service");
26
+ let HttpReplayService = HttpReplayService_1 = class HttpReplayService {
27
+ constructor(httpClient, logQueryService) {
28
+ this.httpClient = httpClient;
29
+ this.logQueryService = logQueryService;
30
+ this.logger = new common_1.Logger(HttpReplayService_1.name);
31
+ }
32
+ replayByLogId(logId_1) {
33
+ return __awaiter(this, arguments, void 0, function* (logId, options = {}) {
34
+ const startTime = Date.now();
35
+ const replayId = this.generateReplayId();
36
+ try {
37
+ const originalLog = yield this.logQueryService.findLogById(logId, true);
38
+ if (!originalLog) {
39
+ throw new Error(`Log with ID ${logId} not found`);
40
+ }
41
+ const requestConfig = this.buildReplayConfig(originalLog, options);
42
+ if (options.logReplay !== false) {
43
+ this.logger.log(`Starting replay for log ${logId} (replay ID: ${replayId})`);
44
+ }
45
+ const response = yield this.executeReplayRequest(requestConfig, options);
46
+ const endTime = Date.now();
47
+ const responseTime = endTime - startTime;
48
+ const result = {
49
+ originalLog,
50
+ requestConfig,
51
+ response,
52
+ responseTime,
53
+ success: true,
54
+ replayTimestamp: new Date().toISOString(),
55
+ replayId,
56
+ };
57
+ if (options.logReplay !== false) {
58
+ this.logger.log(`Replay completed for log ${logId} (replay ID: ${replayId}) in ${responseTime}ms`);
59
+ }
60
+ return result;
61
+ }
62
+ catch (error) {
63
+ const endTime = Date.now();
64
+ const responseTime = endTime - startTime;
65
+ const result = {
66
+ originalLog: {},
67
+ requestConfig: {},
68
+ response: null,
69
+ responseTime,
70
+ success: false,
71
+ error: error.message,
72
+ replayTimestamp: new Date().toISOString(),
73
+ replayId,
74
+ };
75
+ this.logger.error(`Replay failed for log ${logId} (replay ID: ${replayId}): ${error.message}`, error);
76
+ return result;
77
+ }
78
+ });
79
+ }
80
+ replayByRequestId(requestId_1) {
81
+ return __awaiter(this, arguments, void 0, function* (requestId, options = {}) {
82
+ const originalLog = yield this.logQueryService.findLogByRequestId(requestId);
83
+ if (!originalLog) {
84
+ throw new Error(`Log with requestId ${requestId} not found`);
85
+ }
86
+ return this.replayByLogId(originalLog.id, options);
87
+ });
88
+ }
89
+ batchReplay(logIds_1) {
90
+ return __awaiter(this, arguments, void 0, function* (logIds, options = {}, concurrency = 5) {
91
+ const startTime = Date.now();
92
+ this.logger.log(`Starting batch replay for ${logIds.length} logs`);
93
+ const results = [];
94
+ const chunks = this.chunkArray(logIds, concurrency);
95
+ for (const chunk of chunks) {
96
+ const chunkPromises = chunk.map((logId) => __awaiter(this, void 0, void 0, function* () {
97
+ try {
98
+ return yield this.replayByLogId(logId, options);
99
+ }
100
+ catch (error) {
101
+ this.logger.error(`Failed to replay log ${logId}`, error);
102
+ return {
103
+ originalLog: {},
104
+ requestConfig: {},
105
+ response: null,
106
+ responseTime: 0,
107
+ success: false,
108
+ error: error.message,
109
+ replayTimestamp: new Date().toISOString(),
110
+ replayId: this.generateReplayId(),
111
+ };
112
+ }
113
+ }));
114
+ const chunkResults = yield Promise.all(chunkPromises);
115
+ results.push(...chunkResults);
116
+ }
117
+ const successfulRequests = results.filter((r) => r.success).length;
118
+ const failedRequests = results.length - successfulRequests;
119
+ const totalResponseTime = results.reduce((sum, r) => sum + r.responseTime, 0);
120
+ const averageResponseTime = results.length > 0 ? totalResponseTime / results.length : 0;
121
+ const batchResult = {
122
+ totalRequests: results.length,
123
+ successfulRequests,
124
+ failedRequests,
125
+ successRate: results.length > 0 ? (successfulRequests / results.length) * 100 : 0,
126
+ totalResponseTime,
127
+ averageResponseTime,
128
+ results,
129
+ };
130
+ this.logger.log(`Batch replay completed: ${successfulRequests}/${results.length} successful in ${totalResponseTime}ms`);
131
+ return batchResult;
132
+ });
133
+ }
134
+ batchReplayByQuery() {
135
+ return __awaiter(this, arguments, void 0, function* (queryOptions = {}, replayOptions = {}, concurrency = 5) {
136
+ const limitedQueryOptions = Object.assign(Object.assign({}, queryOptions), { limit: Math.min(queryOptions.limit || 50, 100) });
137
+ const queryResult = yield this.logQueryService.findLogs(limitedQueryOptions);
138
+ const logIds = queryResult.logs.map((log) => log.id);
139
+ if (logIds.length === 0) {
140
+ this.logger.log('No logs found for replay query');
141
+ return {
142
+ totalRequests: 0,
143
+ successfulRequests: 0,
144
+ failedRequests: 0,
145
+ successRate: 0,
146
+ totalResponseTime: 0,
147
+ averageResponseTime: 0,
148
+ results: [],
149
+ };
150
+ }
151
+ this.logger.log(`Found ${logIds.length} logs for batch replay`);
152
+ return this.batchReplay(logIds, replayOptions, concurrency);
153
+ });
154
+ }
155
+ replayAndCompare(logId_1) {
156
+ return __awaiter(this, arguments, void 0, function* (logId, options = {}) {
157
+ var _a, _b, _c;
158
+ const originalLog = yield this.logQueryService.findLogById(logId, true);
159
+ if (!originalLog) {
160
+ throw new Error(`Log with ID ${logId} not found`);
161
+ }
162
+ const replayResult = yield this.replayByLogId(logId, options);
163
+ const comparison = {
164
+ statusMatch: originalLog.statusCode === ((_a = replayResult.response) === null || _a === void 0 ? void 0 : _a.status),
165
+ responseTimeDifference: replayResult.responseTime - originalLog.responseTime,
166
+ headersMatch: this.compareHeaders(originalLog.responseHeaders || {}, ((_b = replayResult.response) === null || _b === void 0 ? void 0 : _b.headers) || {}),
167
+ bodyMatch: this.compareBodies(originalLog.responseBody, (_c = replayResult.response) === null || _c === void 0 ? void 0 : _c.data),
168
+ };
169
+ return {
170
+ original: originalLog,
171
+ replay: replayResult,
172
+ comparison,
173
+ };
174
+ });
175
+ }
176
+ buildReplayConfig(log, options) {
177
+ const config = {
178
+ method: log.method,
179
+ url: log.url,
180
+ headers: Object.assign({}, log.headers),
181
+ params: Object.assign({}, log.params),
182
+ };
183
+ if (log.body) {
184
+ try {
185
+ config.data =
186
+ typeof log.body === 'string' ? JSON.parse(log.body) : log.body;
187
+ }
188
+ catch (_a) {
189
+ config.data = log.body;
190
+ }
191
+ }
192
+ if (options.overrideHeaders) {
193
+ config.headers = Object.assign(Object.assign({}, config.headers), options.additionalHeaders);
194
+ }
195
+ else if (options.additionalHeaders) {
196
+ config.headers = Object.assign(Object.assign({}, config.headers), options.additionalHeaders);
197
+ }
198
+ if (options.overrideBody && options.additionalHeaders) {
199
+ }
200
+ if (options.overrideParams && options.metadata) {
201
+ config.params = Object.assign(Object.assign({}, config.params), options.metadata);
202
+ }
203
+ if (options.timeout) {
204
+ config.timeout = options.timeout;
205
+ }
206
+ config.metadata = Object.assign({ originalLogId: log.id, originalRequestId: log.requestId, replayTimestamp: new Date().toISOString(), replayedBy: 'http-replay-service' }, options.metadata);
207
+ return config;
208
+ }
209
+ executeReplayRequest(config, options) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ try {
212
+ return yield this.httpClient.request(config);
213
+ }
214
+ catch (error) {
215
+ throw error;
216
+ }
217
+ });
218
+ }
219
+ generateReplayId() {
220
+ return `replay-${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
221
+ }
222
+ chunkArray(array, size) {
223
+ const chunks = [];
224
+ for (let i = 0; i < array.length; i += size) {
225
+ chunks.push(array.slice(i, i + size));
226
+ }
227
+ return chunks;
228
+ }
229
+ compareHeaders(original, replay) {
230
+ const ignoreHeaders = ['date', 'expires', 'last-modified', 'etag'];
231
+ const originalFiltered = Object.keys(original)
232
+ .filter((key) => !ignoreHeaders.includes(key.toLowerCase()))
233
+ .reduce((obj, key) => {
234
+ obj[key] = original[key];
235
+ return obj;
236
+ }, {});
237
+ const replayFiltered = Object.keys(replay)
238
+ .filter((key) => !ignoreHeaders.includes(key.toLowerCase()))
239
+ .reduce((obj, key) => {
240
+ obj[key] = replay[key];
241
+ return obj;
242
+ }, {});
243
+ return JSON.stringify(originalFiltered) === JSON.stringify(replayFiltered);
244
+ }
245
+ compareBodies(original, replay) {
246
+ if (!original && !replay)
247
+ return true;
248
+ if (!original || !replay)
249
+ return false;
250
+ try {
251
+ const originalParsed = typeof original === 'string' ? JSON.parse(original) : original;
252
+ const replayString = typeof replay === 'string' ? replay : JSON.stringify(replay);
253
+ const replayParsed = JSON.parse(replayString);
254
+ return JSON.stringify(originalParsed) === JSON.stringify(replayParsed);
255
+ }
256
+ catch (_a) {
257
+ return original === replay;
258
+ }
259
+ }
260
+ };
261
+ exports.HttpReplayService = HttpReplayService;
262
+ exports.HttpReplayService = HttpReplayService = HttpReplayService_1 = __decorate([
263
+ (0, common_1.Injectable)(),
264
+ __metadata("design:paramtypes", [http_client_service_1.HttpClientService,
265
+ http_log_query_service_1.HttpLogQueryService])
266
+ ], HttpReplayService);
@@ -23,7 +23,7 @@ exports.HttpLogCleanupService = void 0;
23
23
  const common_1 = require("@nestjs/common");
24
24
  const schedule_1 = require("@nestjs/schedule");
25
25
  const http_log_query_service_1 = require("./http-log-query.service");
26
- const setup_1 = require("../../setup");
26
+ const schedule_decorator_1 = require("../../setup/schedule.decorator");
27
27
  let HttpLogCleanupService = HttpLogCleanupService_1 = class HttpLogCleanupService {
28
28
  constructor(logQueryService, config = {}) {
29
29
  this.logQueryService = logQueryService;
@@ -257,7 +257,7 @@ let HttpLogCleanupService = HttpLogCleanupService_1 = class HttpLogCleanupServic
257
257
  };
258
258
  exports.HttpLogCleanupService = HttpLogCleanupService;
259
259
  __decorate([
260
- (0, setup_1.WorkerCronSmart)(schedule_1.CronExpression.EVERY_DAY_AT_2AM),
260
+ (0, schedule_decorator_1.WorkerCronSmart)(schedule_1.CronExpression.EVERY_DAY_AT_2AM),
261
261
  __metadata("design:type", Function),
262
262
  __metadata("design:paramtypes", []),
263
263
  __metadata("design:returntype", Promise)
@@ -23,7 +23,7 @@ exports.HttpLoggingService = void 0;
23
23
  const common_1 = require("@nestjs/common");
24
24
  const typeorm_1 = require("typeorm");
25
25
  const http_log_entity_1 = require("../entities/http-log.entity");
26
- const request_id_util_1 = require("../../../../http-client/src/utils/request-id.util");
26
+ const request_id_util_1 = require("../utils/request-id.util");
27
27
  const context_extractor_util_1 = require("../utils/context-extractor.util");
28
28
  const call_stack_extractor_util_1 = require("../utils/call-stack-extractor.util");
29
29
  let HttpLoggingService = HttpLoggingService_1 = class HttpLoggingService {
@@ -0,0 +1,4 @@
1
+ export declare function generateRequestId(): string;
2
+ export declare function generateShortRequestId(): string;
3
+ export declare function isValidRequestId(requestId: string): boolean;
4
+ export declare function extractRequestId(headers: Record<string, string>): string | null;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateRequestId = generateRequestId;
4
+ exports.generateShortRequestId = generateShortRequestId;
5
+ exports.isValidRequestId = isValidRequestId;
6
+ exports.extractRequestId = extractRequestId;
7
+ const crypto_1 = require("crypto");
8
+ function generateRequestId() {
9
+ return (0, crypto_1.randomUUID)();
10
+ }
11
+ function generateShortRequestId() {
12
+ return Math.random().toString(36).substring(2, 15);
13
+ }
14
+ function isValidRequestId(requestId) {
15
+ const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
16
+ return uuidRegex.test(requestId);
17
+ }
18
+ function extractRequestId(headers) {
19
+ const requestIdHeaders = [
20
+ 'x-request-id',
21
+ 'x-trace-id',
22
+ 'request-id',
23
+ 'trace-id',
24
+ 'x-correlation-id',
25
+ 'correlation-id',
26
+ ];
27
+ for (const header of requestIdHeaders) {
28
+ const value = headers[header];
29
+ if (value && isValidRequestId(value)) {
30
+ return value;
31
+ }
32
+ }
33
+ return null;
34
+ }
package/index.d.ts CHANGED
@@ -17,3 +17,4 @@ export * from './http-client';
17
17
  export * from './vault';
18
18
  export * from './setup';
19
19
  export * from './health-checker';
20
+ export * from './audit';
package/index.js CHANGED
@@ -33,3 +33,4 @@ __exportStar(require("./http-client"), exports);
33
33
  __exportStar(require("./vault"), exports);
34
34
  __exportStar(require("./setup"), exports);
35
35
  __exportStar(require("./health-checker"), exports);
36
+ __exportStar(require("./audit"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-omni/core",
3
- "version": "3.1.2-8",
3
+ "version": "4.1.2-9",
4
4
  "description": "A comprehensive NestJS framework for building enterprise-grade applications with best practices",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -139,7 +139,11 @@ function bootstrapSetup(AppModule, SetupSwagger) {
139
139
  app.enableShutdownHooks();
140
140
  app.enableVersioning();
141
141
  app.enable('trust proxy');
142
- app.use(bodyParse.json({ limit: '50mb' }), new nestjs_cls_1.ClsMiddleware({
142
+ app.set('query parser', 'extended');
143
+ app.use(bodyParse.urlencoded({
144
+ extended: true,
145
+ parameterLimit: 1000,
146
+ }), bodyParse.json({ limit: '50mb' }), new nestjs_cls_1.ClsMiddleware({
143
147
  saveReq: true,
144
148
  }).use, (0, __1.RequestIdMiddleware)(), (0, __1.PowerByMiddleware)(), (0, __1.OmniAuthMiddleware)(), compression());
145
149
  const reflector = app.get(core_1.Reflector);