Skip to content

Commit 01d1472

Browse files
committed
fix: revert to previous version 1.5.0
1 parent 9e76589 commit 01d1472

11 files changed

+156
-233
lines changed
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
import { UseFilters, UseInterceptors, applyDecorators } from '@nestjs/common';
22
import { RpcExtendedExceptionFilter } from '../filters';
3-
import { RpcLoggingInterceptor } from '../interceptors';
3+
import { RpcContextInterceptor, RpcLoggingInterceptor } from '../interceptors';
4+
import { RegisterControls } from '../decorators/register-controls.decorator';
45

5-
export function RpcExtendedController() {
6-
return applyDecorators(
6+
/**
7+
* Extended RPC controller decorator that applies:
8+
* 1. Standard RPC filters and interceptors
9+
* 2. Automatic control registration
10+
*
11+
* @param prefix Controller prefix (optional)
12+
*/
13+
export function RpcExtendedController(handlerType?: string) {
14+
const decorators = [
15+
// Only add Controller with prefix if prefix is provided
716
UseFilters(RpcExtendedExceptionFilter),
817
UseInterceptors(RpcLoggingInterceptor),
9-
);
18+
UseInterceptors(RpcContextInterceptor),
19+
];
20+
21+
// Add RegisterControls decorator if handlerType is provided
22+
if (handlerType) {
23+
decorators.push(RegisterControls(handlerType));
24+
}
25+
26+
return applyDecorators(...decorators);
1027
}
Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,33 @@
11
import { MessagePattern } from '@nestjs/microservices';
22
import { log } from '../utils';
3+
import { Control } from './register-controls.decorator';
34

4-
export function LoggedMessagePattern(subject: string) {
5+
/**
6+
* Decorator that combines MessagePattern with logging and Control registration.
7+
* This allows a method to be both a message handler and a registered control.
8+
*
9+
* @param subject The message subject pattern
10+
* @param description Optional description for the Control registration
11+
*/
12+
export function LoggedMessagePattern(subject: string, description?: string) {
513
return function (
614
target: any,
715
propertyKey: string,
816
descriptor: PropertyDescriptor,
917
) {
1018
const className = target.constructor.name;
19+
20+
// Log registration
1121
log.info(
1222
`Registering message pattern for subject: ${subject} in class: ${className}`,
1323
);
24+
25+
// Apply the Control decorator if description is provided
26+
if (description) {
27+
Control(description)(target, propertyKey, descriptor);
28+
}
29+
30+
// Apply the MessagePattern decorator
1431
return MessagePattern(subject)(target, propertyKey, descriptor);
1532
};
1633
}

src/frameworks/shared/decorators/register-control.decorator.ts

Lines changed: 0 additions & 107 deletions
This file was deleted.
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { SetMetadata } from '@nestjs/common';
2+
import { HandlerRegistryService } from '@/modules/messaging/domain/usecases/services/handler-registry.service';
3+
import { log } from '../utils';
4+
5+
export const REGISTERED_CONTROLS = 'registered_controls';
6+
7+
export interface ControlMetadata {
8+
description: string;
9+
}
10+
11+
/**
12+
* Decorator for registering a method as a control
13+
*
14+
* @param description Description of what the control does
15+
*/
16+
export const Control = (description: string) =>
17+
SetMetadata<string, ControlMetadata>(REGISTERED_CONTROLS, { description });
18+
19+
/**
20+
* Decorator for registering a handler class with all its control methods.
21+
*
22+
* This decorator automatically detects the HandlerRegistryService from the
23+
* dependency injection container, so you don't need to manually inject it
24+
* in your handler constructor.
25+
*
26+
* Usage:
27+
* ```typescript
28+
* @Injectable()
29+
* @RegisterControls('MyHandlerType')
30+
* export class MyHandler {
31+
* constructor() {
32+
* // No need to inject HandlerRegistryService
33+
* }
34+
*
35+
* @Control('Does something useful')
36+
* async myMethod() {
37+
* // Implementation
38+
* }
39+
* }
40+
* ```
41+
*
42+
* @param handlerType The type of handler (SystemControl, Command, etc.)
43+
*/
44+
export function RegisterControls(handlerType: string) {
45+
return function (target: any) {
46+
// Store the original constructor
47+
const originalConstructor = target;
48+
49+
// Create a new constructor function
50+
const newConstructor: any = function (...args: any[]) {
51+
const instance = new originalConstructor(...args);
52+
53+
// Get the handler registry service from the DI container
54+
const handlerRegistryService = args.find(
55+
(arg) => arg instanceof HandlerRegistryService,
56+
) as HandlerRegistryService;
57+
58+
// Ensure we have access to the registry service
59+
if (!handlerRegistryService) {
60+
log.warn(
61+
`HandlerRegistryService not injected in ${target.name}. Controls will not be registered.`,
62+
);
63+
return instance;
64+
}
65+
66+
// Get all methods from the class prototype
67+
const prototype = Object.getPrototypeOf(instance);
68+
const methodNames = Object.getOwnPropertyNames(prototype).filter(
69+
(prop) => {
70+
// Exclude constructor and private methods (starting with _)
71+
return (
72+
prop !== 'constructor' &&
73+
!prop.startsWith('_') &&
74+
typeof prototype[prop] === 'function'
75+
);
76+
},
77+
);
78+
79+
// Register each method that has the @Control decorator
80+
methodNames.forEach((methodName) => {
81+
const method = prototype[methodName];
82+
const metadata = Reflect.getMetadata(REGISTERED_CONTROLS, method);
83+
84+
if (metadata) {
85+
handlerRegistryService.registerControl(
86+
handlerType,
87+
methodName,
88+
metadata.description,
89+
);
90+
}
91+
});
92+
93+
return instance;
94+
};
95+
96+
// Copy prototype so instanceof operator still works
97+
newConstructor.prototype = originalConstructor.prototype;
98+
99+
// Return the new constructor
100+
return newConstructor;
101+
};
102+
}

src/modules/messaging/domain/usecases/handlers/system-control.handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ import { ConfigRegistryService } from '@/modules/messaging/domain/usecases/servi
1111
import { HandlerRegistryService } from '@/modules/messaging/domain/usecases/services/handler-registry.service';
1212
import { MessagingHandler } from './messaging.handler';
1313
import { SubjectFactory } from '../factories/subject.factory';
14+
import { SYSTEM_CONTROL_MESSAGE_TYPE } from './constant.handler';
1415
import {
1516
GetConfigurationValidator,
1617
GetConfigurationParameterValidator,
1718
GetControlListValidator,
1819
} from '../entities/system-control.validator';
19-
import { SYSTEM_CONTROL_MESSAGE_TYPE } from './constant.handler';
2020

2121
@Injectable()
2222
export class SystemControlHandler extends MessagingHandler {
2323
constructor(
2424
@Inject(MESSAGING_ADAPTER)
2525
private readonly messagingAdapter: IMessagingAdapter,
2626
private readonly configRegistry: ConfigRegistryService,
27-
public readonly handlerRegistry: HandlerRegistryService,
27+
private readonly handlerRegistry: HandlerRegistryService,
2828
) {
2929
super();
3030
}

src/modules/messaging/domain/usecases/handlers/system-monitor.handler.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import { Injectable } from '@nestjs/common';
22
import { MessagingHandler } from './messaging.handler';
33
import { HealthService } from '@/frameworks/health/health.service';
44
import { log } from '@/frameworks';
5-
import { SYSTEM_MONITOR_MESSAGE_TYPE } from './constant.handler';
6-
import { RegisterControl } from '../../../../../frameworks/shared/decorators/register-control.decorator';
75

86
interface IHealthResponse {
97
data: {
@@ -18,11 +16,6 @@ export class SystemMonitorHandler extends MessagingHandler {
1816
super();
1917
}
2018

21-
@RegisterControl(
22-
SYSTEM_MONITOR_MESSAGE_TYPE,
23-
'health',
24-
'Performs a health check on the system and returns the status',
25-
)
2619
public async health() {
2720
try {
2821
log.info('Executing health check command');

src/modules/messaging/domain/usecases/services/control-registration.service.ts

Lines changed: 0 additions & 76 deletions
This file was deleted.

0 commit comments

Comments
 (0)