@takentrade/takentrade-libs 3.0.0 → 3.2.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.
- package/README.md +1 -0
- package/dist/auth/auth.interface.d.ts +8 -0
- package/dist/auth/auth.interface.js +2 -0
- package/dist/auth/decorators/get-user.decorator.d.ts +2 -0
- package/dist/auth/decorators/get-user.decorator.js +26 -0
- package/dist/auth/decorators/index.d.ts +1 -0
- package/dist/auth/decorators/index.js +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.js +1 -0
- package/dist/common/utils/string.utils.d.ts +10 -2
- package/dist/common/utils/string.utils.js +30 -13
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/metrics/metrics.interface.d.ts +0 -53
- package/dist/metrics/metrics.interface.js +0 -12
- package/dist/monitoring/alerting.service.d.ts +82 -0
- package/dist/monitoring/alerting.service.js +290 -0
- package/dist/monitoring/index.d.ts +5 -0
- package/dist/monitoring/index.js +21 -0
- package/dist/monitoring/monitoring.interface.d.ts +102 -0
- package/dist/monitoring/monitoring.interface.js +10 -0
- package/dist/monitoring/monitoring.module.d.ts +8 -0
- package/dist/monitoring/monitoring.module.js +44 -0
- package/dist/monitoring/sentry.service.d.ts +65 -0
- package/dist/monitoring/sentry.service.js +218 -0
- package/dist/monitoring/uptime.service.d.ts +59 -0
- package/dist/monitoring/uptime.service.js +213 -0
- package/dist/resilience/circuit-breaker.interface.d.ts +0 -75
- package/dist/resilience/circuit-breaker.interface.js +0 -6
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/helpers/date.util.d.ts +8 -0
- package/dist/utils/helpers/date.util.js +30 -0
- package/dist/utils/helpers/decimal.util.d.ts +9 -0
- package/dist/utils/helpers/decimal.util.js +31 -0
- package/dist/utils/helpers/format.util.d.ts +64 -0
- package/dist/utils/helpers/format.util.js +162 -0
- package/dist/utils/helpers/penalty.util.d.ts +25 -0
- package/dist/utils/helpers/penalty.util.js +40 -0
- package/dist/utils/helpers/referral.util.d.ts +4 -0
- package/dist/utils/helpers/referral.util.js +53 -0
- package/dist/utils/helpers/role.util.d.ts +8 -0
- package/dist/utils/helpers/role.util.js +18 -0
- package/dist/utils/helpers/validation.util.d.ts +62 -0
- package/dist/utils/helpers/validation.util.js +138 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +7 -0
- package/package.json +4 -1
|
@@ -0,0 +1,213 @@
|
|
|
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 UptimeService_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.UptimeService = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
/**
|
|
13
|
+
* Uptime Monitoring Service
|
|
14
|
+
*
|
|
15
|
+
* Tracks service availability and generates SLA reports
|
|
16
|
+
*/
|
|
17
|
+
let UptimeService = UptimeService_1 = class UptimeService {
|
|
18
|
+
logger = new common_1.Logger(UptimeService_1.name);
|
|
19
|
+
healthChecks = new Map();
|
|
20
|
+
healthResults = new Map();
|
|
21
|
+
downtimeTracking = new Map();
|
|
22
|
+
config;
|
|
23
|
+
checkIntervals = new Map();
|
|
24
|
+
constructor(config) {
|
|
25
|
+
this.config = config || { enabled: true, checkInterval: 60000 };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Register a health check
|
|
29
|
+
*/
|
|
30
|
+
registerHealthCheck(check) {
|
|
31
|
+
this.healthChecks.set(check.name, check);
|
|
32
|
+
this.healthResults.set(check.name, []);
|
|
33
|
+
this.downtimeTracking.set(check.name, 0);
|
|
34
|
+
if (this.config.enabled) {
|
|
35
|
+
this.startHealthCheck(check);
|
|
36
|
+
}
|
|
37
|
+
this.logger.log(`Health check '${check.name}' registered`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Start periodic health check
|
|
41
|
+
*/
|
|
42
|
+
startHealthCheck(check) {
|
|
43
|
+
const interval = check.interval || this.config.checkInterval || 60000;
|
|
44
|
+
const timer = setInterval(async () => {
|
|
45
|
+
await this.runHealthCheck(check.name);
|
|
46
|
+
}, interval);
|
|
47
|
+
this.checkIntervals.set(check.name, timer);
|
|
48
|
+
// Run immediately
|
|
49
|
+
this.runHealthCheck(check.name);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Run a health check
|
|
53
|
+
*/
|
|
54
|
+
async runHealthCheck(name) {
|
|
55
|
+
const check = this.healthChecks.get(name);
|
|
56
|
+
if (!check) {
|
|
57
|
+
throw new Error(`Health check '${name}' not found`);
|
|
58
|
+
}
|
|
59
|
+
const startTime = Date.now();
|
|
60
|
+
let result;
|
|
61
|
+
try {
|
|
62
|
+
const timeout = check.timeout || 5000;
|
|
63
|
+
await Promise.race([
|
|
64
|
+
check.check(),
|
|
65
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Health check timeout')), timeout)),
|
|
66
|
+
]);
|
|
67
|
+
result = {
|
|
68
|
+
name,
|
|
69
|
+
status: 'healthy',
|
|
70
|
+
responseTime: Date.now() - startTime,
|
|
71
|
+
timestamp: new Date(),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
result = {
|
|
76
|
+
name,
|
|
77
|
+
status: 'unhealthy',
|
|
78
|
+
responseTime: Date.now() - startTime,
|
|
79
|
+
error: error instanceof Error ? error.message : String(error),
|
|
80
|
+
timestamp: new Date(),
|
|
81
|
+
};
|
|
82
|
+
// Track downtime
|
|
83
|
+
const currentDowntime = this.downtimeTracking.get(name) || 0;
|
|
84
|
+
this.downtimeTracking.set(name, currentDowntime + (check.interval || this.config.checkInterval || 60000));
|
|
85
|
+
this.logger.warn(`Health check '${name}' failed: ${result.error}`);
|
|
86
|
+
}
|
|
87
|
+
// Store result
|
|
88
|
+
const results = this.healthResults.get(name) || [];
|
|
89
|
+
results.push(result);
|
|
90
|
+
// Keep only last 1000 results
|
|
91
|
+
if (results.length > 1000) {
|
|
92
|
+
results.shift();
|
|
93
|
+
}
|
|
94
|
+
this.healthResults.set(name, results);
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get current health status
|
|
99
|
+
*/
|
|
100
|
+
async getHealthStatus(name) {
|
|
101
|
+
if (name) {
|
|
102
|
+
const results = this.healthResults.get(name);
|
|
103
|
+
return results ? [results[results.length - 1]] : [];
|
|
104
|
+
}
|
|
105
|
+
// Get latest result for all checks
|
|
106
|
+
const allResults = [];
|
|
107
|
+
for (const [checkName, results] of this.healthResults.entries()) {
|
|
108
|
+
if (results.length > 0) {
|
|
109
|
+
allResults.push(results[results.length - 1]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return allResults;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get uptime percentage
|
|
116
|
+
*/
|
|
117
|
+
getUptime(name, periodMs) {
|
|
118
|
+
const results = this.healthResults.get(name);
|
|
119
|
+
if (!results || results.length === 0) {
|
|
120
|
+
return 100;
|
|
121
|
+
}
|
|
122
|
+
const now = Date.now();
|
|
123
|
+
const period = periodMs || 24 * 60 * 60 * 1000; // 24 hours default
|
|
124
|
+
const startTime = now - period;
|
|
125
|
+
const relevantResults = results.filter((r) => r.timestamp.getTime() >= startTime);
|
|
126
|
+
if (relevantResults.length === 0) {
|
|
127
|
+
return 100;
|
|
128
|
+
}
|
|
129
|
+
const healthyCount = relevantResults.filter((r) => r.status === 'healthy').length;
|
|
130
|
+
return (healthyCount / relevantResults.length) * 100;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get SLA report
|
|
134
|
+
*/
|
|
135
|
+
getSLAReport(name, period = '30d') {
|
|
136
|
+
const periodMs = this.parsePeriod(period);
|
|
137
|
+
const now = new Date();
|
|
138
|
+
const startTime = new Date(now.getTime() - periodMs);
|
|
139
|
+
const results = this.healthResults.get(name) || [];
|
|
140
|
+
const relevantResults = results.filter((r) => r.timestamp.getTime() >= startTime.getTime());
|
|
141
|
+
const healthyCount = relevantResults.filter((r) => r.status === 'healthy').length;
|
|
142
|
+
const uptime = relevantResults.length > 0
|
|
143
|
+
? (healthyCount / relevantResults.length) * 100
|
|
144
|
+
: 100;
|
|
145
|
+
const downtime = this.downtimeTracking.get(name) || 0;
|
|
146
|
+
const incidents = relevantResults.filter((r) => r.status === 'unhealthy').length;
|
|
147
|
+
return {
|
|
148
|
+
service: name,
|
|
149
|
+
uptime,
|
|
150
|
+
downtime,
|
|
151
|
+
incidents,
|
|
152
|
+
period,
|
|
153
|
+
startTime,
|
|
154
|
+
endTime: now,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Parse period string to milliseconds
|
|
159
|
+
*/
|
|
160
|
+
parsePeriod(period) {
|
|
161
|
+
const match = period.match(/^(\d+)([hdwm])$/);
|
|
162
|
+
if (!match) {
|
|
163
|
+
throw new Error(`Invalid period format: ${period}`);
|
|
164
|
+
}
|
|
165
|
+
const value = parseInt(match[1], 10);
|
|
166
|
+
const unit = match[2];
|
|
167
|
+
const multipliers = {
|
|
168
|
+
h: 60 * 60 * 1000,
|
|
169
|
+
d: 24 * 60 * 60 * 1000,
|
|
170
|
+
w: 7 * 24 * 60 * 60 * 1000,
|
|
171
|
+
m: 30 * 24 * 60 * 60 * 1000,
|
|
172
|
+
};
|
|
173
|
+
return value * multipliers[unit];
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Stop all health checks
|
|
177
|
+
*/
|
|
178
|
+
stopAllHealthChecks() {
|
|
179
|
+
for (const [name, timer] of this.checkIntervals.entries()) {
|
|
180
|
+
clearInterval(timer);
|
|
181
|
+
this.logger.log(`Health check '${name}' stopped`);
|
|
182
|
+
}
|
|
183
|
+
this.checkIntervals.clear();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Stop specific health check
|
|
187
|
+
*/
|
|
188
|
+
stopHealthCheck(name) {
|
|
189
|
+
const timer = this.checkIntervals.get(name);
|
|
190
|
+
if (timer) {
|
|
191
|
+
clearInterval(timer);
|
|
192
|
+
this.checkIntervals.delete(name);
|
|
193
|
+
this.logger.log(`Health check '${name}' stopped`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get all registered health checks
|
|
198
|
+
*/
|
|
199
|
+
getHealthChecks() {
|
|
200
|
+
return Array.from(this.healthChecks.keys());
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Cleanup on destroy
|
|
204
|
+
*/
|
|
205
|
+
onModuleDestroy() {
|
|
206
|
+
this.stopAllHealthChecks();
|
|
207
|
+
this.logger.log('Uptime service shut down');
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
exports.UptimeService = UptimeService;
|
|
211
|
+
exports.UptimeService = UptimeService = UptimeService_1 = __decorate([
|
|
212
|
+
(0, common_1.Injectable)()
|
|
213
|
+
], UptimeService);
|
|
@@ -1,88 +1,25 @@
|
|
|
1
1
|
import CircuitBreaker from 'opossum';
|
|
2
|
-
/**
|
|
3
|
-
* Circuit breaker state enum
|
|
4
|
-
*/
|
|
5
2
|
export declare enum CircuitState {
|
|
6
3
|
CLOSED = "closed",
|
|
7
4
|
OPEN = "open",
|
|
8
5
|
HALF_OPEN = "halfOpen"
|
|
9
6
|
}
|
|
10
|
-
/**
|
|
11
|
-
* Circuit breaker options based on Opossum configuration
|
|
12
|
-
* @see https://nodeshift.dev/opossum/
|
|
13
|
-
*/
|
|
14
7
|
export interface CircuitBreakerOptions {
|
|
15
|
-
/**
|
|
16
|
-
* The time in milliseconds that action should be allowed to execute before timing out.
|
|
17
|
-
* @default 10000 (10 seconds)
|
|
18
|
-
*/
|
|
19
8
|
timeout?: number;
|
|
20
|
-
/**
|
|
21
|
-
* The number of times the circuit can fail before opening.
|
|
22
|
-
* @default 50
|
|
23
|
-
*/
|
|
24
9
|
errorThresholdPercentage?: number;
|
|
25
|
-
/**
|
|
26
|
-
* The time in milliseconds to wait before setting the breaker to halfOpen state.
|
|
27
|
-
* @default 30000 (30 seconds)
|
|
28
|
-
*/
|
|
29
10
|
resetTimeout?: number;
|
|
30
|
-
/**
|
|
31
|
-
* The rolling statistical window in milliseconds.
|
|
32
|
-
* @default 10000 (10 seconds)
|
|
33
|
-
*/
|
|
34
11
|
rollingCountTimeout?: number;
|
|
35
|
-
/**
|
|
36
|
-
* The number of buckets the rolling statistical window is divided into.
|
|
37
|
-
* @default 10
|
|
38
|
-
*/
|
|
39
12
|
rollingCountBuckets?: number;
|
|
40
|
-
/**
|
|
41
|
-
* The name of the circuit breaker (for logging and metrics).
|
|
42
|
-
*/
|
|
43
13
|
name?: string;
|
|
44
|
-
/**
|
|
45
|
-
* The capacity of the internal event bus.
|
|
46
|
-
* @default 100
|
|
47
|
-
*/
|
|
48
14
|
capacity?: number;
|
|
49
|
-
/**
|
|
50
|
-
* Whether to enable snapshots for metrics.
|
|
51
|
-
* @default false
|
|
52
|
-
*/
|
|
53
15
|
enableSnapshots?: boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Whether to allow warm up period (ignore errors initially).
|
|
56
|
-
* @default false
|
|
57
|
-
*/
|
|
58
16
|
allowWarmUp?: boolean;
|
|
59
|
-
/**
|
|
60
|
-
* The number of requests to allow during warm up.
|
|
61
|
-
* @default 0
|
|
62
|
-
*/
|
|
63
17
|
volumeThreshold?: number;
|
|
64
|
-
/**
|
|
65
|
-
* Custom error filter function to determine if an error should trip the circuit.
|
|
66
|
-
*/
|
|
67
18
|
errorFilter?: (error: any) => boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Whether to cache the result of successful calls.
|
|
70
|
-
* @default false
|
|
71
|
-
*/
|
|
72
19
|
cache?: boolean;
|
|
73
|
-
/**
|
|
74
|
-
* Cache TTL in milliseconds.
|
|
75
|
-
* @default 0
|
|
76
|
-
*/
|
|
77
20
|
cacheTTL?: number;
|
|
78
|
-
/**
|
|
79
|
-
* Custom cache key generator function.
|
|
80
|
-
*/
|
|
81
21
|
cacheGetKey?: (...args: any[]) => string;
|
|
82
22
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Circuit breaker statistics
|
|
85
|
-
*/
|
|
86
23
|
export interface CircuitBreakerStats {
|
|
87
24
|
fires: number;
|
|
88
25
|
failures: number;
|
|
@@ -98,9 +35,6 @@ export interface CircuitBreakerStats {
|
|
|
98
35
|
latencyMean: number;
|
|
99
36
|
latencyTimes: number[];
|
|
100
37
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Circuit breaker event types
|
|
103
|
-
*/
|
|
104
38
|
export declare enum CircuitBreakerEvent {
|
|
105
39
|
FIRE = "fire",
|
|
106
40
|
SUCCESS = "success",
|
|
@@ -116,19 +50,10 @@ export declare enum CircuitBreakerEvent {
|
|
|
116
50
|
CACHE_HIT = "cacheHit",
|
|
117
51
|
CACHE_MISS = "cacheMiss"
|
|
118
52
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Circuit breaker instance wrapper
|
|
121
|
-
*/
|
|
122
53
|
export interface CircuitBreakerInstance<T = any, R = any> {
|
|
123
54
|
breaker: CircuitBreaker<T[], R>;
|
|
124
55
|
name: string;
|
|
125
56
|
options: CircuitBreakerOptions;
|
|
126
57
|
}
|
|
127
|
-
/**
|
|
128
|
-
* Fallback function type
|
|
129
|
-
*/
|
|
130
58
|
export type FallbackFunction<T = any> = (...args: any[]) => T | Promise<T>;
|
|
131
|
-
/**
|
|
132
|
-
* Health check function type
|
|
133
|
-
*/
|
|
134
59
|
export type HealthCheckFunction = () => Promise<boolean>;
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CircuitBreakerEvent = exports.CircuitState = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Circuit breaker state enum
|
|
6
|
-
*/
|
|
7
4
|
var CircuitState;
|
|
8
5
|
(function (CircuitState) {
|
|
9
6
|
CircuitState["CLOSED"] = "closed";
|
|
10
7
|
CircuitState["OPEN"] = "open";
|
|
11
8
|
CircuitState["HALF_OPEN"] = "halfOpen";
|
|
12
9
|
})(CircuitState || (exports.CircuitState = CircuitState = {}));
|
|
13
|
-
/**
|
|
14
|
-
* Circuit breaker event types
|
|
15
|
-
*/
|
|
16
10
|
var CircuitBreakerEvent;
|
|
17
11
|
(function (CircuitBreakerEvent) {
|
|
18
12
|
CircuitBreakerEvent["FIRE"] = "fire";
|