@dumanarge/xssrv-shared-lib 1.0.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.
@@ -0,0 +1,111 @@
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 FeatureFlagService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FeatureFlagService = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const config_1 = require("@nestjs/config");
16
+ let FeatureFlagService = FeatureFlagService_1 = class FeatureFlagService {
17
+ config;
18
+ logger = new common_1.Logger(FeatureFlagService_1.name);
19
+ flags = new Map();
20
+ pollTimer = null;
21
+ POLL_INTERVAL = 30000;
22
+ KV_PREFIX;
23
+ constructor(config) {
24
+ this.config = config;
25
+ this.KV_PREFIX = 'xenonsmart-backend/config/feature-flags';
26
+ }
27
+ async onModuleInit() {
28
+ await this.loadFlags();
29
+ this.pollTimer = setInterval(() => this.loadFlags(), this.POLL_INTERVAL);
30
+ }
31
+ onModuleDestroy() {
32
+ if (this.pollTimer)
33
+ clearInterval(this.pollTimer);
34
+ }
35
+ async isEnabled(flagName, tenantId) {
36
+ const flag = this.flags.get(flagName);
37
+ if (!flag)
38
+ return false;
39
+ if (tenantId && flag.tenants && flag.tenants !== '*') {
40
+ const allowed = Array.isArray(flag.tenants) ? flag.tenants : [flag.tenants];
41
+ if (!allowed.includes(tenantId))
42
+ return false;
43
+ }
44
+ if (flag.rollout !== undefined && flag.rollout < 100) {
45
+ if (tenantId) {
46
+ const hash = this.simpleHash(tenantId + flagName);
47
+ if (hash % 100 >= flag.rollout)
48
+ return false;
49
+ }
50
+ }
51
+ return flag.value;
52
+ }
53
+ async getConfig(flagName) {
54
+ const flag = this.flags.get(flagName);
55
+ return flag?.config || null;
56
+ }
57
+ getAllFlags() {
58
+ return new Map(this.flags);
59
+ }
60
+ async loadFlags() {
61
+ try {
62
+ const consulHost = this.config.get('consul.host', 'localhost');
63
+ const consulPort = this.config.get('consul.port', 8500);
64
+ const response = await fetch(`http://${consulHost}:${consulPort}/v1/kv/${this.KV_PREFIX}?recurse=true`, { signal: AbortSignal.timeout(5000) });
65
+ if (response.ok) {
66
+ const entries = await response.json();
67
+ for (const entry of entries) {
68
+ const key = entry.Key.replace(`${this.KV_PREFIX}/`, '');
69
+ const value = JSON.parse(Buffer.from(entry.Value, 'base64').toString());
70
+ this.flags.set(key, value);
71
+ }
72
+ this.logger.debug(`Loaded ${this.flags.size} feature flags from Consul`);
73
+ }
74
+ }
75
+ catch (error) {
76
+ this.logger.warn(`Failed to load feature flags from Consul, using cache: ${error.message}`);
77
+ if (this.flags.size === 0) {
78
+ this.loadDefaults();
79
+ }
80
+ }
81
+ }
82
+ loadDefaults() {
83
+ this.flags.set('device_twin_enabled', { value: true, rollout: 100, tenants: '*' });
84
+ this.flags.set('cqrs_read_model_enabled', { value: true, rollout: 100, tenants: '*' });
85
+ this.flags.set('graphql_subscriptions_enabled', { value: true, rollout: 100, tenants: '*' });
86
+ this.flags.set('timescaledb_continuous_aggregates', { value: true, rollout: 100, tenants: '*' });
87
+ this.flags.set('tuya_adapter_enabled', { value: true, rollout: 100, tenants: '*' });
88
+ this.flags.set('meari_adapter_enabled', { value: false, rollout: 0 });
89
+ this.flags.set('shelly_adapter_enabled', { value: false, rollout: 0 });
90
+ this.flags.set('batch_signal_processing', {
91
+ value: true, rollout: 100, tenants: '*',
92
+ config: { batch_size: 500, flush_interval_ms: 100 },
93
+ });
94
+ this.logger.warn(`Loaded ${this.flags.size} default feature flags`);
95
+ }
96
+ simpleHash(str) {
97
+ let hash = 0;
98
+ for (let i = 0; i < str.length; i++) {
99
+ const char = str.charCodeAt(i);
100
+ hash = ((hash << 5) - hash) + char;
101
+ hash |= 0;
102
+ }
103
+ return Math.abs(hash);
104
+ }
105
+ };
106
+ exports.FeatureFlagService = FeatureFlagService;
107
+ exports.FeatureFlagService = FeatureFlagService = FeatureFlagService_1 = __decorate([
108
+ (0, common_1.Injectable)(),
109
+ __metadata("design:paramtypes", [config_1.ConfigService])
110
+ ], FeatureFlagService);
111
+ //# sourceMappingURL=feature-flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-flags.js","sourceRoot":"","sources":["../../src/config/feature-flags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { OnApplicationShutdown } from '@nestjs/common';
2
+ export interface ShutdownHook {
3
+ name: string;
4
+ priority: number;
5
+ shutdown: () => Promise<void>;
6
+ }
7
+ export declare class GracefulShutdownService implements OnApplicationShutdown {
8
+ private readonly logger;
9
+ private readonly hooks;
10
+ private isShuttingDown;
11
+ registerHook(hook: ShutdownHook): void;
12
+ onApplicationShutdown(signal?: string): Promise<void>;
13
+ }
14
+ export declare class GracefulShutdownModule {
15
+ }
16
+ export declare function enableGracefulShutdown(app: any): void;
@@ -0,0 +1,62 @@
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 GracefulShutdownService_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.GracefulShutdownModule = exports.GracefulShutdownService = void 0;
11
+ exports.enableGracefulShutdown = enableGracefulShutdown;
12
+ const common_1 = require("@nestjs/common");
13
+ let GracefulShutdownService = GracefulShutdownService_1 = class GracefulShutdownService {
14
+ logger = new common_1.Logger(GracefulShutdownService_1.name);
15
+ hooks = [];
16
+ isShuttingDown = false;
17
+ registerHook(hook) {
18
+ this.hooks.push(hook);
19
+ this.hooks.sort((a, b) => a.priority - b.priority);
20
+ this.logger.log(`Registered shutdown hook: ${hook.name} (priority: ${hook.priority})`);
21
+ }
22
+ async onApplicationShutdown(signal) {
23
+ if (this.isShuttingDown)
24
+ return;
25
+ this.isShuttingDown = true;
26
+ this.logger.warn(`Graceful shutdown initiated (signal: ${signal})`);
27
+ const startTime = Date.now();
28
+ for (const hook of this.hooks) {
29
+ try {
30
+ this.logger.log(`Executing shutdown hook: ${hook.name}`);
31
+ const hookStart = Date.now();
32
+ await Promise.race([
33
+ hook.shutdown(),
34
+ new Promise((_, reject) => setTimeout(() => reject(new Error(`Timeout after 10s`)), 10000)),
35
+ ]);
36
+ this.logger.log(`${hook.name} completed in ${Date.now() - hookStart}ms`);
37
+ }
38
+ catch (error) {
39
+ this.logger.error(`Shutdown hook ${hook.name} failed: ${error.message}`);
40
+ }
41
+ }
42
+ this.logger.warn(`Graceful shutdown completed in ${Date.now() - startTime}ms`);
43
+ }
44
+ };
45
+ exports.GracefulShutdownService = GracefulShutdownService;
46
+ exports.GracefulShutdownService = GracefulShutdownService = GracefulShutdownService_1 = __decorate([
47
+ (0, common_1.Injectable)()
48
+ ], GracefulShutdownService);
49
+ let GracefulShutdownModule = class GracefulShutdownModule {
50
+ };
51
+ exports.GracefulShutdownModule = GracefulShutdownModule;
52
+ exports.GracefulShutdownModule = GracefulShutdownModule = __decorate([
53
+ (0, common_1.Global)(),
54
+ (0, common_1.Module)({
55
+ providers: [GracefulShutdownService],
56
+ exports: [GracefulShutdownService],
57
+ })
58
+ ], GracefulShutdownModule);
59
+ function enableGracefulShutdown(app) {
60
+ app.enableShutdownHooks();
61
+ }
62
+ //# sourceMappingURL=graceful-shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graceful-shutdown.js","sourceRoot":"","sources":["../../src/config/graceful-shutdown.ts"],"names":[],"mappings":";;;;;;;;;;AA+DA,wDAEC;AA3DD,2CAA2F;AASpF,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IACjB,MAAM,GAAG,IAAI,eAAM,CAAC,yBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,KAAK,GAAmB,EAAE,CAAC;IACpC,cAAc,GAAG,KAAK,CAAC;IAE/B,YAAY,CAAC,IAAkB;QAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACzF,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,MAAe;QACzC,IAAI,IAAI,CAAC,cAAc;YAAE,OAAO;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAE3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,MAAM,GAAG,CAAC,CAAC;QACpE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,4BAA4B,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBACzD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,IAAI,CAAC,QAAQ,EAAE;oBACf,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACxB,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC,EAAE,KAAK,CAAC,CAChE;iBACF,CAAC,CAAC;gBACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CAAC,CAAC;YAC3E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,CAAC,IAAI,YAAa,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,kCAAkC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,IAAI,CAAC,CAAC;IACjF,CAAC;CACF,CAAA;AApCY,0DAAuB;kCAAvB,uBAAuB;IADnC,IAAA,mBAAU,GAAE;GACA,uBAAuB,CAoCnC;AAOM,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;CAAG,CAAA;AAAzB,wDAAsB;iCAAtB,sBAAsB;IALlC,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,uBAAuB,CAAC;QACpC,OAAO,EAAE,CAAC,uBAAuB,CAAC;KACnC,CAAC;GACW,sBAAsB,CAAG;AAKtC,SAAgB,sBAAsB,CAAC,GAAQ;IAC7C,GAAG,CAAC,mBAAmB,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { HealthCheckService, HealthIndicator, HealthIndicatorResult } from '@nestjs/terminus';
2
+ export declare class RedisHealthIndicator extends HealthIndicator {
3
+ private readonly redis;
4
+ constructor(redis: any);
5
+ isHealthy(key: string): Promise<HealthIndicatorResult>;
6
+ }
7
+ export declare class RabbitMQHealthIndicator extends HealthIndicator {
8
+ private readonly connection;
9
+ constructor(connection: any);
10
+ isHealthy(key: string): Promise<HealthIndicatorResult>;
11
+ }
12
+ export declare class HealthController {
13
+ private health;
14
+ constructor(health: HealthCheckService);
15
+ liveness(): Promise<import("@nestjs/terminus").HealthCheckResult<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>, Partial<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>>, Partial<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>>>>;
16
+ readiness(): Promise<import("@nestjs/terminus").HealthCheckResult<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>, Partial<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>>, Partial<HealthIndicatorResult<string, import("@nestjs/terminus").HealthIndicatorStatus, Record<string, any>>>>>;
17
+ }
18
+ export declare class HealthModule {
19
+ }
@@ -0,0 +1,93 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.HealthModule = exports.HealthController = exports.RabbitMQHealthIndicator = exports.RedisHealthIndicator = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const terminus_1 = require("@nestjs/terminus");
15
+ const common_2 = require("@nestjs/common");
16
+ const terminus_2 = require("@nestjs/terminus");
17
+ class RedisHealthIndicator extends terminus_2.HealthIndicator {
18
+ redis;
19
+ constructor(redis) {
20
+ super();
21
+ this.redis = redis;
22
+ }
23
+ async isHealthy(key) {
24
+ try {
25
+ const result = await this.redis.ping();
26
+ return this.getStatus(key, result === 'PONG');
27
+ }
28
+ catch (e) {
29
+ return this.getStatus(key, false, { message: e.message });
30
+ }
31
+ }
32
+ }
33
+ exports.RedisHealthIndicator = RedisHealthIndicator;
34
+ class RabbitMQHealthIndicator extends terminus_2.HealthIndicator {
35
+ connection;
36
+ constructor(connection) {
37
+ super();
38
+ this.connection = connection;
39
+ }
40
+ async isHealthy(key) {
41
+ try {
42
+ const isConnected = this.connection?.isConnected?.() ?? false;
43
+ return this.getStatus(key, isConnected);
44
+ }
45
+ catch (e) {
46
+ return this.getStatus(key, false, { message: e.message });
47
+ }
48
+ }
49
+ }
50
+ exports.RabbitMQHealthIndicator = RabbitMQHealthIndicator;
51
+ let HealthController = class HealthController {
52
+ health;
53
+ constructor(health) {
54
+ this.health = health;
55
+ }
56
+ liveness() {
57
+ return this.health.check([]);
58
+ }
59
+ readiness() {
60
+ return this.health.check([]);
61
+ }
62
+ };
63
+ exports.HealthController = HealthController;
64
+ __decorate([
65
+ (0, common_2.Get)('live'),
66
+ (0, terminus_2.HealthCheck)(),
67
+ __metadata("design:type", Function),
68
+ __metadata("design:paramtypes", []),
69
+ __metadata("design:returntype", void 0)
70
+ ], HealthController.prototype, "liveness", null);
71
+ __decorate([
72
+ (0, common_2.Get)('ready'),
73
+ (0, terminus_2.HealthCheck)(),
74
+ __metadata("design:type", Function),
75
+ __metadata("design:paramtypes", []),
76
+ __metadata("design:returntype", void 0)
77
+ ], HealthController.prototype, "readiness", null);
78
+ exports.HealthController = HealthController = __decorate([
79
+ (0, common_2.Controller)('health'),
80
+ __metadata("design:paramtypes", [terminus_2.HealthCheckService])
81
+ ], HealthController);
82
+ let HealthModule = class HealthModule {
83
+ };
84
+ exports.HealthModule = HealthModule;
85
+ exports.HealthModule = HealthModule = __decorate([
86
+ (0, common_1.Module)({
87
+ imports: [terminus_1.TerminusModule],
88
+ controllers: [HealthController],
89
+ providers: [RedisHealthIndicator, RabbitMQHealthIndicator],
90
+ exports: [terminus_1.TerminusModule, RedisHealthIndicator, RabbitMQHealthIndicator],
91
+ })
92
+ ], HealthModule);
93
+ //# sourceMappingURL=health.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.module.js","sourceRoot":"","sources":["../../src/health/health.module.ts"],"names":[],"mappings":";;;;;;;;;;;;AASA,2CAAwC;AACxC,+CAAkD;AAClD,2CAAiD;AACjD,+CAM0B;AAG1B,MAAa,oBAAqB,SAAQ,0BAAe;IAC1B;IAA7B,YAA6B,KAAU;QACrC,KAAK,EAAE,CAAC;QADmB,UAAK,GAAL,KAAK,CAAK;IAEvC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF;AAbD,oDAaC;AAGD,MAAa,uBAAwB,SAAQ,0BAAe;IAC7B;IAA7B,YAA6B,UAAe;QAC1C,KAAK,EAAE,CAAC;QADmB,eAAU,GAAV,UAAU,CAAK;IAE5C,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,IAAI,KAAK,CAAC;YAC9D,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF;AAbD,0DAaC;AAIM,IAAM,gBAAgB,GAAtB,MAAM,gBAAgB;IACP;IAApB,YAAoB,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;IAAG,CAAC;IAQlD,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IASD,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;CACF,CAAA;AAvBY,4CAAgB;AAS3B;IAFC,IAAA,YAAG,EAAC,MAAM,CAAC;IACX,IAAA,sBAAW,GAAE;;;;gDAGb;AASD;IAFC,IAAA,YAAG,EAAC,OAAO,CAAC;IACZ,IAAA,sBAAW,GAAE;;;;iDAGb;2BAtBU,gBAAgB;IAD5B,IAAA,mBAAU,EAAC,QAAQ,CAAC;qCAES,6BAAkB;GADnC,gBAAgB,CAuB5B;AAQM,IAAM,YAAY,GAAlB,MAAM,YAAY;CAAG,CAAA;AAAf,oCAAY;uBAAZ,YAAY;IANxB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,yBAAc,CAAC;QACzB,WAAW,EAAE,CAAC,gBAAgB,CAAC;QAC/B,SAAS,EAAE,CAAC,oBAAoB,EAAE,uBAAuB,CAAC;QAC1D,OAAO,EAAE,CAAC,yBAAc,EAAE,oBAAoB,EAAE,uBAAuB,CAAC;KACzE,CAAC;GACW,YAAY,CAAG"}
@@ -0,0 +1,8 @@
1
+ export { Span, trace, context, SpanStatusCode } from './tracing/span.decorator';
2
+ export { LoggingModule, PINO_LOGGER_CONFIG } from './logging/logging.module';
3
+ export { HealthModule, HealthController, RedisHealthIndicator, RabbitMQHealthIndicator, } from './health/health.module';
4
+ export { OutboxEvent, OutboxRepository, OutboxWorker, EventPublisher, RabbitMQEventPublisher, } from './outbox/outbox.module';
5
+ export { TenantContext, TenantMiddleware, TenantGuard, createPrismaTenantMiddleware, extractTenantFromGrpcMetadata, } from './auth/tenant.middleware';
6
+ export { AuditInterceptor, AuditEntry } from './auth/audit.interceptor';
7
+ export { GracefulShutdownService, GracefulShutdownModule, enableGracefulShutdown, ShutdownHook } from './config/graceful-shutdown';
8
+ export { FeatureFlagService, FeatureFlag } from './config/feature-flags';
package/dist/index.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeatureFlagService = exports.enableGracefulShutdown = exports.GracefulShutdownModule = exports.GracefulShutdownService = exports.AuditInterceptor = exports.extractTenantFromGrpcMetadata = exports.createPrismaTenantMiddleware = exports.TenantGuard = exports.TenantMiddleware = exports.TenantContext = exports.RabbitMQEventPublisher = exports.EventPublisher = exports.OutboxWorker = exports.OutboxRepository = exports.RabbitMQHealthIndicator = exports.RedisHealthIndicator = exports.HealthController = exports.HealthModule = exports.PINO_LOGGER_CONFIG = exports.LoggingModule = exports.SpanStatusCode = exports.context = exports.trace = exports.Span = void 0;
4
+ var span_decorator_1 = require("./tracing/span.decorator");
5
+ Object.defineProperty(exports, "Span", { enumerable: true, get: function () { return span_decorator_1.Span; } });
6
+ Object.defineProperty(exports, "trace", { enumerable: true, get: function () { return span_decorator_1.trace; } });
7
+ Object.defineProperty(exports, "context", { enumerable: true, get: function () { return span_decorator_1.context; } });
8
+ Object.defineProperty(exports, "SpanStatusCode", { enumerable: true, get: function () { return span_decorator_1.SpanStatusCode; } });
9
+ var logging_module_1 = require("./logging/logging.module");
10
+ Object.defineProperty(exports, "LoggingModule", { enumerable: true, get: function () { return logging_module_1.LoggingModule; } });
11
+ Object.defineProperty(exports, "PINO_LOGGER_CONFIG", { enumerable: true, get: function () { return logging_module_1.PINO_LOGGER_CONFIG; } });
12
+ var health_module_1 = require("./health/health.module");
13
+ Object.defineProperty(exports, "HealthModule", { enumerable: true, get: function () { return health_module_1.HealthModule; } });
14
+ Object.defineProperty(exports, "HealthController", { enumerable: true, get: function () { return health_module_1.HealthController; } });
15
+ Object.defineProperty(exports, "RedisHealthIndicator", { enumerable: true, get: function () { return health_module_1.RedisHealthIndicator; } });
16
+ Object.defineProperty(exports, "RabbitMQHealthIndicator", { enumerable: true, get: function () { return health_module_1.RabbitMQHealthIndicator; } });
17
+ var outbox_module_1 = require("./outbox/outbox.module");
18
+ Object.defineProperty(exports, "OutboxRepository", { enumerable: true, get: function () { return outbox_module_1.OutboxRepository; } });
19
+ Object.defineProperty(exports, "OutboxWorker", { enumerable: true, get: function () { return outbox_module_1.OutboxWorker; } });
20
+ Object.defineProperty(exports, "EventPublisher", { enumerable: true, get: function () { return outbox_module_1.EventPublisher; } });
21
+ Object.defineProperty(exports, "RabbitMQEventPublisher", { enumerable: true, get: function () { return outbox_module_1.RabbitMQEventPublisher; } });
22
+ var tenant_middleware_1 = require("./auth/tenant.middleware");
23
+ Object.defineProperty(exports, "TenantContext", { enumerable: true, get: function () { return tenant_middleware_1.TenantContext; } });
24
+ Object.defineProperty(exports, "TenantMiddleware", { enumerable: true, get: function () { return tenant_middleware_1.TenantMiddleware; } });
25
+ Object.defineProperty(exports, "TenantGuard", { enumerable: true, get: function () { return tenant_middleware_1.TenantGuard; } });
26
+ Object.defineProperty(exports, "createPrismaTenantMiddleware", { enumerable: true, get: function () { return tenant_middleware_1.createPrismaTenantMiddleware; } });
27
+ Object.defineProperty(exports, "extractTenantFromGrpcMetadata", { enumerable: true, get: function () { return tenant_middleware_1.extractTenantFromGrpcMetadata; } });
28
+ var audit_interceptor_1 = require("./auth/audit.interceptor");
29
+ Object.defineProperty(exports, "AuditInterceptor", { enumerable: true, get: function () { return audit_interceptor_1.AuditInterceptor; } });
30
+ var graceful_shutdown_1 = require("./config/graceful-shutdown");
31
+ Object.defineProperty(exports, "GracefulShutdownService", { enumerable: true, get: function () { return graceful_shutdown_1.GracefulShutdownService; } });
32
+ Object.defineProperty(exports, "GracefulShutdownModule", { enumerable: true, get: function () { return graceful_shutdown_1.GracefulShutdownModule; } });
33
+ Object.defineProperty(exports, "enableGracefulShutdown", { enumerable: true, get: function () { return graceful_shutdown_1.enableGracefulShutdown; } });
34
+ var feature_flags_1 = require("./config/feature-flags");
35
+ Object.defineProperty(exports, "FeatureFlagService", { enumerable: true, get: function () { return feature_flags_1.FeatureFlagService; } });
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,2DAAgF;AAAvE,sGAAA,IAAI,OAAA;AAAE,uGAAA,KAAK,OAAA;AAAE,yGAAA,OAAO,OAAA;AAAE,gHAAA,cAAc,OAAA;AAG7C,2DAA6E;AAApE,+GAAA,aAAa,OAAA;AAAE,oHAAA,kBAAkB,OAAA;AAG1C,wDAKgC;AAJ9B,6GAAA,YAAY,OAAA;AACZ,iHAAA,gBAAgB,OAAA;AAChB,qHAAA,oBAAoB,OAAA;AACpB,wHAAA,uBAAuB,OAAA;AAIzB,wDAMgC;AAJ9B,iHAAA,gBAAgB,OAAA;AAChB,6GAAA,YAAY,OAAA;AACZ,+GAAA,cAAc,OAAA;AACd,uHAAA,sBAAsB,OAAA;AAIxB,8DAMkC;AALhC,kHAAA,aAAa,OAAA;AACb,qHAAA,gBAAgB,OAAA;AAChB,gHAAA,WAAW,OAAA;AACX,iIAAA,4BAA4B,OAAA;AAC5B,kIAAA,6BAA6B,OAAA;AAG/B,8DAAwE;AAA/D,qHAAA,gBAAgB,OAAA;AAGzB,gEAAmI;AAA1H,4HAAA,uBAAuB,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAAE,2HAAA,sBAAsB,OAAA;AAChF,wDAAyE;AAAhE,mHAAA,kBAAkB,OAAA"}
@@ -0,0 +1,45 @@
1
+ export declare const PINO_LOGGER_CONFIG: {
2
+ pinoHttp: {
3
+ level: string;
4
+ transport: {
5
+ target: string;
6
+ options: {
7
+ colorize: boolean;
8
+ singleLine: boolean;
9
+ };
10
+ };
11
+ autoLogging: {
12
+ ignore: (req: any) => boolean;
13
+ };
14
+ serializers: {
15
+ req: (req: any) => {
16
+ method: any;
17
+ url: any;
18
+ headers: {
19
+ 'x-request-id': any;
20
+ 'x-tenant-id': any;
21
+ 'user-agent': any;
22
+ };
23
+ };
24
+ res: (res: any) => {
25
+ statusCode: any;
26
+ };
27
+ };
28
+ customProps: () => {
29
+ traceId: string;
30
+ spanId: string;
31
+ traceFlags: number;
32
+ } | {
33
+ traceId?: undefined;
34
+ spanId?: undefined;
35
+ traceFlags?: undefined;
36
+ };
37
+ redact: {
38
+ paths: string[];
39
+ censor: string;
40
+ };
41
+ genReqId: (req: any) => any;
42
+ };
43
+ };
44
+ export declare class LoggingModule {
45
+ }
@@ -0,0 +1,74 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.LoggingModule = exports.PINO_LOGGER_CONFIG = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const nestjs_pino_1 = require("nestjs-pino");
12
+ const api_1 = require("@opentelemetry/api");
13
+ exports.PINO_LOGGER_CONFIG = {
14
+ pinoHttp: {
15
+ level: process.env.LOG_LEVEL || 'info',
16
+ transport: process.env.NODE_ENV === 'development'
17
+ ? { target: 'pino-pretty', options: { colorize: true, singleLine: true } }
18
+ : undefined,
19
+ autoLogging: {
20
+ ignore: (req) => {
21
+ return req.url === '/health/live' || req.url === '/health/ready' || req.url === '/metrics';
22
+ },
23
+ },
24
+ serializers: {
25
+ req: (req) => ({
26
+ method: req.method,
27
+ url: req.url,
28
+ headers: {
29
+ 'x-request-id': req.headers['x-request-id'],
30
+ 'x-tenant-id': req.headers['x-tenant-id'],
31
+ 'user-agent': req.headers['user-agent'],
32
+ },
33
+ }),
34
+ res: (res) => ({
35
+ statusCode: res.statusCode,
36
+ }),
37
+ },
38
+ customProps: () => {
39
+ const activeSpan = api_1.trace.getActiveSpan();
40
+ if (activeSpan) {
41
+ const spanContext = activeSpan.spanContext();
42
+ return {
43
+ traceId: spanContext.traceId,
44
+ spanId: spanContext.spanId,
45
+ traceFlags: spanContext.traceFlags,
46
+ };
47
+ }
48
+ return {};
49
+ },
50
+ redact: {
51
+ paths: [
52
+ 'req.headers.authorization',
53
+ 'req.headers.cookie',
54
+ 'req.body.password',
55
+ 'req.body.secret',
56
+ 'req.body.token',
57
+ ],
58
+ censor: '[REDACTED]',
59
+ },
60
+ genReqId: (req) => {
61
+ return req.headers['x-request-id'] || crypto.randomUUID();
62
+ },
63
+ },
64
+ };
65
+ let LoggingModule = class LoggingModule {
66
+ };
67
+ exports.LoggingModule = LoggingModule;
68
+ exports.LoggingModule = LoggingModule = __decorate([
69
+ (0, common_1.Module)({
70
+ imports: [nestjs_pino_1.LoggerModule.forRoot(exports.PINO_LOGGER_CONFIG)],
71
+ exports: [nestjs_pino_1.LoggerModule],
72
+ })
73
+ ], LoggingModule);
74
+ //# sourceMappingURL=logging.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.module.js","sourceRoot":"","sources":["../../src/logging/logging.module.ts"],"names":[],"mappings":";;;;;;;;;AAUA,2CAAwC;AACxC,6CAA+D;AAC/D,4CAAoD;AAEvC,QAAA,kBAAkB,GAAG;IAChC,QAAQ,EAAE;QACR,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;QACtC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;YAC/C,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;YAC1E,CAAC,CAAC,SAAS;QACb,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,GAAQ,EAAE,EAAE;gBAEnB,OAAO,GAAG,CAAC,GAAG,KAAK,cAAc,IAAI,GAAG,CAAC,GAAG,KAAK,eAAe,IAAI,GAAG,CAAC,GAAG,KAAK,UAAU,CAAC;YAC7F,CAAC;SACF;QACD,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;gBAClB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,OAAO,EAAE;oBACP,cAAc,EAAE,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;oBAC3C,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC;oBACzC,YAAY,EAAE,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC;iBACxC;aACF,CAAC;YACF,GAAG,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;gBAClB,UAAU,EAAE,GAAG,CAAC,UAAU;aAC3B,CAAC;SACH;QACD,WAAW,EAAE,GAAG,EAAE;YAChB,MAAM,UAAU,GAAG,WAAK,CAAC,aAAa,EAAE,CAAC;YACzC,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;gBAC7C,OAAO;oBACL,OAAO,EAAE,WAAW,CAAC,OAAO;oBAC5B,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,UAAU,EAAE,WAAW,CAAC,UAAU;iBACnC,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,EAAE;YACN,KAAK,EAAE;gBACL,2BAA2B;gBAC3B,oBAAoB;gBACpB,mBAAmB;gBACnB,iBAAiB;gBACjB,gBAAgB;aACjB;YACD,MAAM,EAAE,YAAY;SACrB;QACD,QAAQ,EAAE,CAAC,GAAQ,EAAE,EAAE;YACrB,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC5D,CAAC;KACF;CACF,CAAC;AAMK,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IAJzB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,0BAAgB,CAAC,OAAO,CAAC,0BAAkB,CAAC,CAAC;QACvD,OAAO,EAAE,CAAC,0BAAgB,CAAC;KAC5B,CAAC;GACW,aAAa,CAAG"}
@@ -0,0 +1,44 @@
1
+ import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
2
+ export interface OutboxEvent {
3
+ id?: string;
4
+ aggregateType: string;
5
+ aggregateId: string;
6
+ eventType: string;
7
+ payload: Record<string, any>;
8
+ metadata?: Record<string, any>;
9
+ createdAt?: Date;
10
+ processedAt?: Date | null;
11
+ retryCount?: number;
12
+ maxRetries?: number;
13
+ }
14
+ export declare class OutboxRepository {
15
+ private readonly prisma;
16
+ private readonly logger;
17
+ constructor(prisma: any);
18
+ createInTransaction(tx: any, event: OutboxEvent): Promise<any>;
19
+ fetchUnprocessed(batchSize?: number): Promise<OutboxEvent[]>;
20
+ markProcessed(eventId: string): Promise<void>;
21
+ incrementRetry(eventId: string): Promise<void>;
22
+ }
23
+ export declare abstract class EventPublisher {
24
+ abstract publish(routingKey: string, payload: any): Promise<void>;
25
+ }
26
+ export declare class OutboxWorker implements OnModuleInit, OnModuleDestroy {
27
+ private readonly outboxRepo;
28
+ private readonly eventPublisher;
29
+ private readonly logger;
30
+ private intervalId;
31
+ private readonly pollIntervalMs;
32
+ private readonly batchSize;
33
+ private isProcessing;
34
+ constructor(outboxRepo: OutboxRepository, eventPublisher: EventPublisher);
35
+ onModuleInit(): void;
36
+ onModuleDestroy(): void;
37
+ private processOutbox;
38
+ }
39
+ export declare class RabbitMQEventPublisher extends EventPublisher {
40
+ private readonly amqpConnection;
41
+ private readonly logger;
42
+ constructor(amqpConnection: any);
43
+ publish(routingKey: string, payload: any): Promise<void>;
44
+ }