@takentrade/takentrade-libs 2.0.8 → 3.1.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/LICENSE +87 -0
- package/README.md +113 -743
- 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/health/health.controller.js +0 -2
- package/dist/common/index.d.ts +0 -2
- package/dist/common/index.js +0 -2
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/metrics/circuit-breaker-metrics.service.d.ts +61 -0
- package/dist/metrics/circuit-breaker-metrics.service.js +149 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/index.js +21 -0
- package/dist/metrics/metrics-registry.d.ts +50 -0
- package/dist/metrics/metrics-registry.js +156 -0
- package/dist/metrics/metrics-updater.d.ts +32 -0
- package/dist/metrics/metrics-updater.js +102 -0
- package/dist/metrics/metrics.controller.d.ts +11 -0
- package/dist/metrics/metrics.controller.js +32 -0
- package/dist/metrics/metrics.interface.d.ts +53 -0
- package/dist/metrics/metrics.interface.js +23 -0
- package/dist/metrics/metrics.module.d.ts +11 -0
- package/dist/metrics/metrics.module.js +39 -0
- package/dist/metrics/metrics.service.d.ts +50 -0
- package/dist/metrics/metrics.service.js +165 -0
- 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-event-handler.d.ts +16 -0
- package/dist/resilience/circuit-breaker-event-handler.js +70 -0
- package/dist/resilience/circuit-breaker-factory.d.ts +19 -0
- package/dist/resilience/circuit-breaker-factory.js +51 -0
- package/dist/resilience/circuit-breaker-stats.service.d.ts +37 -0
- package/dist/resilience/circuit-breaker-stats.service.js +69 -0
- package/dist/resilience/circuit-breaker.interface.d.ts +59 -0
- package/dist/resilience/circuit-breaker.interface.js +25 -0
- package/dist/{common/circuit-breaker → resilience}/circuit-breaker.module.js +1 -0
- package/dist/resilience/circuit-breaker.service.d.ts +119 -0
- package/dist/resilience/circuit-breaker.service.js +234 -0
- package/dist/resilience/index.d.ts +3 -0
- package/dist/resilience/index.js +19 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/dto/pagination.js +0 -6
- 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/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/index.d.ts +4 -0
- package/dist/utils/index.js +4 -0
- package/package.json +8 -2
- package/dist/common/circuit-breaker/circuit-breaker.service.d.ts +0 -13
- package/dist/common/circuit-breaker/circuit-breaker.service.js +0 -120
- package/dist/common/circuit-breaker/circuit-breaker.types.d.ts +0 -19
- package/dist/common/circuit-breaker/circuit-breaker.types.js +0 -9
- /package/dist/{common/circuit-breaker → resilience}/circuit-breaker.module.d.ts +0 -0
|
@@ -9,7 +9,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.PaginationQueryDto = void 0;
|
|
10
10
|
const class_validator_1 = require("class-validator");
|
|
11
11
|
const class_transformer_1 = require("class-transformer");
|
|
12
|
-
const swagger_1 = require("@nestjs/swagger");
|
|
13
12
|
class PaginationQueryDto {
|
|
14
13
|
page;
|
|
15
14
|
limit;
|
|
@@ -19,31 +18,26 @@ class PaginationQueryDto {
|
|
|
19
18
|
}
|
|
20
19
|
exports.PaginationQueryDto = PaginationQueryDto;
|
|
21
20
|
__decorate([
|
|
22
|
-
(0, swagger_1.ApiPropertyOptional)({ minimum: 1, default: 1 }),
|
|
23
21
|
(0, class_transformer_1.Type)(() => Number),
|
|
24
22
|
(0, class_validator_1.IsInt)(),
|
|
25
23
|
(0, class_validator_1.Min)(1),
|
|
26
24
|
(0, class_validator_1.IsOptional)()
|
|
27
25
|
], PaginationQueryDto.prototype, "page", void 0);
|
|
28
26
|
__decorate([
|
|
29
|
-
(0, swagger_1.ApiPropertyOptional)({ minimum: 1, maximum: 100, default: 10 }),
|
|
30
27
|
(0, class_transformer_1.Type)(() => Number),
|
|
31
28
|
(0, class_validator_1.IsInt)(),
|
|
32
29
|
(0, class_validator_1.Min)(1),
|
|
33
30
|
(0, class_validator_1.IsOptional)()
|
|
34
31
|
], PaginationQueryDto.prototype, "limit", void 0);
|
|
35
32
|
__decorate([
|
|
36
|
-
(0, swagger_1.ApiPropertyOptional)(),
|
|
37
33
|
(0, class_validator_1.IsString)(),
|
|
38
34
|
(0, class_validator_1.IsOptional)()
|
|
39
35
|
], PaginationQueryDto.prototype, "search", void 0);
|
|
40
36
|
__decorate([
|
|
41
|
-
(0, swagger_1.ApiPropertyOptional)(),
|
|
42
37
|
(0, class_validator_1.IsString)(),
|
|
43
38
|
(0, class_validator_1.IsOptional)()
|
|
44
39
|
], PaginationQueryDto.prototype, "sortBy", void 0);
|
|
45
40
|
__decorate([
|
|
46
|
-
(0, swagger_1.ApiPropertyOptional)({ enum: ['asc', 'desc'], default: 'desc' }),
|
|
47
41
|
(0, class_validator_1.IsEnum)(['asc', 'desc']),
|
|
48
42
|
(0, class_validator_1.IsOptional)()
|
|
49
43
|
], PaginationQueryDto.prototype, "sortOrder", void 0);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isToday = exports.calculateNextDate = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Calculate next date based on frequency
|
|
6
|
+
*/
|
|
7
|
+
const calculateNextDate = (frequency, lastDate) => {
|
|
8
|
+
const nextDate = new Date(lastDate);
|
|
9
|
+
const frequencyMap = {
|
|
10
|
+
DAILY: () => nextDate.setDate(nextDate.getDate() + 1),
|
|
11
|
+
WEEKLY: () => nextDate.setDate(nextDate.getDate() + 7),
|
|
12
|
+
MONTHLY: () => nextDate.setMonth(nextDate.getMonth() + 1),
|
|
13
|
+
};
|
|
14
|
+
const calculateFn = frequencyMap[frequency];
|
|
15
|
+
if (!calculateFn)
|
|
16
|
+
throw new Error('Invalid frequency');
|
|
17
|
+
calculateFn();
|
|
18
|
+
return nextDate;
|
|
19
|
+
};
|
|
20
|
+
exports.calculateNextDate = calculateNextDate;
|
|
21
|
+
/**
|
|
22
|
+
* Check if a given date is today
|
|
23
|
+
*/
|
|
24
|
+
const isToday = (date) => {
|
|
25
|
+
const today = new Date();
|
|
26
|
+
return (date.getDate() === today.getDate() &&
|
|
27
|
+
date.getMonth() === today.getMonth() &&
|
|
28
|
+
date.getFullYear() === today.getFullYear());
|
|
29
|
+
};
|
|
30
|
+
exports.isToday = isToday;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Decimal from 'decimal.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a value to Decimal
|
|
4
|
+
*/
|
|
5
|
+
export declare const toDecimal: (value: number | string | Decimal) => Decimal;
|
|
6
|
+
/**
|
|
7
|
+
* Convert Decimal to Prisma-compatible number
|
|
8
|
+
*/
|
|
9
|
+
export declare const toPrismaDecimal: (value: Decimal) => number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.toPrismaDecimal = exports.toDecimal = void 0;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const DEFAULT_DECIMAL_PLACES = 4;
|
|
9
|
+
decimal_js_1.default.set({ precision: 20, rounding: decimal_js_1.default.ROUND_HALF_UP });
|
|
10
|
+
/**
|
|
11
|
+
* Convert a value to Decimal
|
|
12
|
+
*/
|
|
13
|
+
const toDecimal = (value) => {
|
|
14
|
+
try {
|
|
15
|
+
return new decimal_js_1.default(value);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
throw new Error(`Invalid decimal value: ${value}`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
exports.toDecimal = toDecimal;
|
|
22
|
+
/**
|
|
23
|
+
* Convert Decimal to Prisma-compatible number
|
|
24
|
+
*/
|
|
25
|
+
const toPrismaDecimal = (value) => {
|
|
26
|
+
if (!decimal_js_1.default.isDecimal(value)) {
|
|
27
|
+
throw new Error('Value must be a Decimal instance');
|
|
28
|
+
}
|
|
29
|
+
return value.toDecimalPlaces(DEFAULT_DECIMAL_PLACES).toNumber();
|
|
30
|
+
};
|
|
31
|
+
exports.toPrismaDecimal = toPrismaDecimal;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateReferralCode = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
/**
|
|
39
|
+
* Generate a unique referral code in format TNT-XXXX-XXXX
|
|
40
|
+
*/
|
|
41
|
+
const generateReferralCode = () => {
|
|
42
|
+
const chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
|
|
43
|
+
const generateRandomPart = (length) => {
|
|
44
|
+
const randomBytes = crypto.randomBytes(length);
|
|
45
|
+
return Array.from(randomBytes)
|
|
46
|
+
.map((x) => chars[x % chars.length])
|
|
47
|
+
.join('');
|
|
48
|
+
};
|
|
49
|
+
const firstPart = generateRandomPart(4);
|
|
50
|
+
const secondPart = generateRandomPart(4);
|
|
51
|
+
return `TNT-${firstPart}-${secondPart}`;
|
|
52
|
+
};
|
|
53
|
+
exports.generateReferralCode = generateReferralCode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBaseRole = exports.isAdminRole = void 0;
|
|
4
|
+
const BASE_ROLE = 'USER';
|
|
5
|
+
/**
|
|
6
|
+
* Check if role is an admin role
|
|
7
|
+
*/
|
|
8
|
+
const isAdminRole = (roleName) => {
|
|
9
|
+
return roleName !== BASE_ROLE;
|
|
10
|
+
};
|
|
11
|
+
exports.isAdminRole = isAdminRole;
|
|
12
|
+
/**
|
|
13
|
+
* Get base role
|
|
14
|
+
*/
|
|
15
|
+
const getBaseRole = () => {
|
|
16
|
+
return BASE_ROLE;
|
|
17
|
+
};
|
|
18
|
+
exports.getBaseRole = getBaseRole;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -14,6 +14,10 @@ export * from './utils';
|
|
|
14
14
|
export * from './interfaces';
|
|
15
15
|
export * from './dto';
|
|
16
16
|
export * from './enums';
|
|
17
|
+
export * from './helpers/decimal.util';
|
|
18
|
+
export * from './helpers/date.util';
|
|
19
|
+
export * from './helpers/role.util';
|
|
20
|
+
export * from './helpers/referral.util';
|
|
17
21
|
/**
|
|
18
22
|
* A set of shared utilities across the application.
|
|
19
23
|
*/
|
package/dist/utils/index.js
CHANGED
|
@@ -54,6 +54,10 @@ __exportStar(require("./utils"), exports);
|
|
|
54
54
|
__exportStar(require("./interfaces"), exports);
|
|
55
55
|
__exportStar(require("./dto"), exports);
|
|
56
56
|
__exportStar(require("./enums"), exports);
|
|
57
|
+
__exportStar(require("./helpers/decimal.util"), exports);
|
|
58
|
+
__exportStar(require("./helpers/date.util"), exports);
|
|
59
|
+
__exportStar(require("./helpers/role.util"), exports);
|
|
60
|
+
__exportStar(require("./helpers/referral.util"), exports);
|
|
57
61
|
/**
|
|
58
62
|
* A set of shared utilities across the application.
|
|
59
63
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@takentrade/takentrade-libs",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "TakeNTrade shared libraries",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -36,16 +36,21 @@
|
|
|
36
36
|
"@nestjs/jwt": "^11.0.1",
|
|
37
37
|
"@nestjs/microservices": "^11.1.9",
|
|
38
38
|
"@nestjs/passport": "^11.0.5",
|
|
39
|
-
"@nestjs/swagger": "^11.2.3",
|
|
40
39
|
"@nestjs/terminus": "^11.0.0",
|
|
40
|
+
"@sentry/node": "^10.27.0",
|
|
41
|
+
"@sentry/tracing": "^7.120.4",
|
|
41
42
|
"class-transformer": "^0.5.1",
|
|
42
43
|
"class-validator": "^0.14.3",
|
|
43
44
|
"cloudinary": "^2.8.0",
|
|
45
|
+
"cockatiel": "^3.2.1",
|
|
44
46
|
"country-codes-list": "^2.0.0",
|
|
47
|
+
"decimal.js": "^10.6.0",
|
|
45
48
|
"ioredis": "^5.8.2",
|
|
46
49
|
"joi": "^18.0.2",
|
|
47
50
|
"jsonwebtoken": "^9.0.2",
|
|
48
51
|
"object-hash": "^3.0.0",
|
|
52
|
+
"opossum": "^9.0.0",
|
|
53
|
+
"prom-client": "^15.1.3",
|
|
49
54
|
"rxjs": "^7.8.2",
|
|
50
55
|
"tsup": "^8.5.1",
|
|
51
56
|
"uuid": "^13.0.0"
|
|
@@ -57,6 +62,7 @@
|
|
|
57
62
|
"@types/multer": "^2.0.0",
|
|
58
63
|
"@types/node": "^24.10.1",
|
|
59
64
|
"@types/object-hash": "^3.0.6",
|
|
65
|
+
"@types/opossum": "^8.1.9",
|
|
60
66
|
"@types/passport": "^1.0.17",
|
|
61
67
|
"jest": "^30.2.0",
|
|
62
68
|
"prettier": "^3.6.2",
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { CircuitBreaker, CircuitBreakerOptions, CircuitState } from './circuit-breaker.types';
|
|
2
|
-
export declare class CircuitBreakerService {
|
|
3
|
-
private readonly logger;
|
|
4
|
-
private readonly breakers;
|
|
5
|
-
createBreaker(name: string, options?: Partial<CircuitBreakerOptions>): CircuitBreaker;
|
|
6
|
-
private startHealthCheck;
|
|
7
|
-
execute<T>(name: string, operation: () => Promise<T>): Promise<T>;
|
|
8
|
-
private onSuccess;
|
|
9
|
-
private onFailure;
|
|
10
|
-
private setState;
|
|
11
|
-
getState(name: string): CircuitState;
|
|
12
|
-
reset(name: string): void;
|
|
13
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
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 CircuitBreakerService_1;
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.CircuitBreakerService = void 0;
|
|
11
|
-
const common_1 = require("@nestjs/common");
|
|
12
|
-
const circuit_breaker_types_1 = require("./circuit-breaker.types");
|
|
13
|
-
let CircuitBreakerService = CircuitBreakerService_1 = class CircuitBreakerService {
|
|
14
|
-
logger = new common_1.Logger(CircuitBreakerService_1.name);
|
|
15
|
-
breakers = new Map();
|
|
16
|
-
createBreaker(name, options = {}) {
|
|
17
|
-
const defaultOptions = {
|
|
18
|
-
failureThreshold: 5,
|
|
19
|
-
resetTimeout: 60000,
|
|
20
|
-
monitorTimeout: 30000,
|
|
21
|
-
healthCheckInterval: 5000,
|
|
22
|
-
};
|
|
23
|
-
const finalOptions = { ...defaultOptions, ...options };
|
|
24
|
-
const breaker = {
|
|
25
|
-
name,
|
|
26
|
-
state: circuit_breaker_types_1.CircuitState.CLOSED,
|
|
27
|
-
failures: 0,
|
|
28
|
-
lastFailureTime: null,
|
|
29
|
-
lastSuccessTime: null,
|
|
30
|
-
options: finalOptions,
|
|
31
|
-
};
|
|
32
|
-
this.breakers.set(name, breaker);
|
|
33
|
-
this.startHealthCheck(name);
|
|
34
|
-
return breaker;
|
|
35
|
-
}
|
|
36
|
-
startHealthCheck(name) {
|
|
37
|
-
const interval = setInterval(() => {
|
|
38
|
-
const breaker = this.breakers.get(name);
|
|
39
|
-
if (!breaker) {
|
|
40
|
-
clearInterval(interval);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (breaker.state === circuit_breaker_types_1.CircuitState.OPEN) {
|
|
44
|
-
const now = Date.now();
|
|
45
|
-
const resetTime = breaker.lastFailureTime
|
|
46
|
-
? breaker.lastFailureTime + breaker.options.resetTimeout
|
|
47
|
-
: 0;
|
|
48
|
-
if (now >= resetTime) {
|
|
49
|
-
this.setState(name, circuit_breaker_types_1.CircuitState.HALF_OPEN);
|
|
50
|
-
this.logger.log(`Circuit ${name} moved to HALF_OPEN state for testing`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}, this.breakers.get(name)?.options.healthCheckInterval);
|
|
54
|
-
}
|
|
55
|
-
async execute(name, operation) {
|
|
56
|
-
const breaker = this.breakers.get(name);
|
|
57
|
-
if (!breaker) {
|
|
58
|
-
throw new Error(`Circuit breaker ${name} not found`);
|
|
59
|
-
}
|
|
60
|
-
if (breaker.state === circuit_breaker_types_1.CircuitState.OPEN) {
|
|
61
|
-
throw new Error(`Circuit ${name} is OPEN`);
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
const result = await operation();
|
|
65
|
-
this.onSuccess(name);
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
this.onFailure(name);
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
onSuccess(name) {
|
|
74
|
-
const breaker = this.breakers.get(name);
|
|
75
|
-
if (!breaker)
|
|
76
|
-
return;
|
|
77
|
-
breaker.failures = 0;
|
|
78
|
-
breaker.lastSuccessTime = Date.now();
|
|
79
|
-
if (breaker.state === circuit_breaker_types_1.CircuitState.HALF_OPEN) {
|
|
80
|
-
this.setState(name, circuit_breaker_types_1.CircuitState.CLOSED);
|
|
81
|
-
this.logger.log(`Circuit ${name} closed after successful test`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
onFailure(name) {
|
|
85
|
-
const breaker = this.breakers.get(name);
|
|
86
|
-
if (!breaker)
|
|
87
|
-
return;
|
|
88
|
-
breaker.failures++;
|
|
89
|
-
breaker.lastFailureTime = Date.now();
|
|
90
|
-
if (breaker.state === circuit_breaker_types_1.CircuitState.CLOSED &&
|
|
91
|
-
breaker.failures >= breaker.options.failureThreshold) {
|
|
92
|
-
this.setState(name, circuit_breaker_types_1.CircuitState.OPEN);
|
|
93
|
-
this.logger.warn(`Circuit ${name} opened after ${breaker.failures} failures`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
setState(name, state) {
|
|
97
|
-
const breaker = this.breakers.get(name);
|
|
98
|
-
if (breaker) {
|
|
99
|
-
breaker.state = state;
|
|
100
|
-
this.breakers.set(name, breaker);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
getState(name) {
|
|
104
|
-
return this.breakers.get(name)?.state || circuit_breaker_types_1.CircuitState.CLOSED;
|
|
105
|
-
}
|
|
106
|
-
reset(name) {
|
|
107
|
-
const breaker = this.breakers.get(name);
|
|
108
|
-
if (breaker) {
|
|
109
|
-
breaker.failures = 0;
|
|
110
|
-
breaker.state = circuit_breaker_types_1.CircuitState.CLOSED;
|
|
111
|
-
breaker.lastFailureTime = null;
|
|
112
|
-
breaker.lastSuccessTime = null;
|
|
113
|
-
this.breakers.set(name, breaker);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
exports.CircuitBreakerService = CircuitBreakerService;
|
|
118
|
-
exports.CircuitBreakerService = CircuitBreakerService = CircuitBreakerService_1 = __decorate([
|
|
119
|
-
(0, common_1.Injectable)()
|
|
120
|
-
], CircuitBreakerService);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export declare enum CircuitState {
|
|
2
|
-
CLOSED = "CLOSED",
|
|
3
|
-
OPEN = "OPEN",
|
|
4
|
-
HALF_OPEN = "HALF_OPEN"
|
|
5
|
-
}
|
|
6
|
-
export interface CircuitBreakerOptions {
|
|
7
|
-
failureThreshold: number;
|
|
8
|
-
resetTimeout: number;
|
|
9
|
-
monitorTimeout: number;
|
|
10
|
-
healthCheckInterval: number;
|
|
11
|
-
}
|
|
12
|
-
export interface CircuitBreaker {
|
|
13
|
-
name: string;
|
|
14
|
-
state: CircuitState;
|
|
15
|
-
failures: number;
|
|
16
|
-
lastFailureTime: number | null;
|
|
17
|
-
lastSuccessTime: number | null;
|
|
18
|
-
options: CircuitBreakerOptions;
|
|
19
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CircuitState = void 0;
|
|
4
|
-
var CircuitState;
|
|
5
|
-
(function (CircuitState) {
|
|
6
|
-
CircuitState["CLOSED"] = "CLOSED";
|
|
7
|
-
CircuitState["OPEN"] = "OPEN";
|
|
8
|
-
CircuitState["HALF_OPEN"] = "HALF_OPEN";
|
|
9
|
-
})(CircuitState || (exports.CircuitState = CircuitState = {}));
|
|
File without changes
|