@@ -458,7 +458,7 @@ export function HttpCode(status: number): MethodDecorator {
458458 * return { data: '...' };
459459 * }
460460 */
461- export function Header ( name : string , value : string ) : MethodDecorator {
461+ export function Header ( name : string , value : string ) : MethodDecorator & ClassDecorator {
462462 return Headers ( name , value ) ;
463463}
464464
@@ -491,11 +491,19 @@ export function Header(name: string, value: string): MethodDecorator {
491491 *
492492 * ```
493493 */
494- export function Headers ( headers : Record < string , string > | string , value ?: string ) : MethodDecorator {
495- return ( target , propertyKey ) => {
496- const existing : Record < string , string > = Reflect . getMetadata ( HEADER_KEY , target , propertyKey ) || { } ;
497- const newHeaders = typeof headers === 'string' ? { [ headers ] : value ! } : headers ;
498- Reflect . defineMetadata ( HEADER_KEY , { ...existing , ...newHeaders } , target , propertyKey ) ;
494+ export function Headers ( headers : Record < string , string > | string , value ?: string ) : MethodDecorator & ClassDecorator {
495+ return ( target : any , propertyKey ?: string | symbol ) => {
496+ if ( typeof propertyKey === 'undefined' ) {
497+ // Class decorator
498+ const existing : Record < string , string > = Reflect . getMetadata ( HEADER_KEY , target ) || { } ;
499+ const newHeaders = typeof headers === 'string' ? { [ headers ] : value ! } : headers ;
500+ Reflect . defineMetadata ( HEADER_KEY , { ...existing , ...newHeaders } , target ) ;
501+ } else {
502+ // Method decorator
503+ const existing : Record < string , string > = Reflect . getMetadata ( HEADER_KEY , target , propertyKey ) || { } ;
504+ const newHeaders = typeof headers === 'string' ? { [ headers ] : value ! } : headers ;
505+ Reflect . defineMetadata ( HEADER_KEY , { ...existing , ...newHeaders } , target , propertyKey ) ;
506+ }
499507 } ;
500508}
501509
@@ -552,6 +560,8 @@ export function After(fn: Function): MethodDecorator {
552560 * Decorator that requires specific roles for accessing a route.
553561 * Must be used with authentication middleware.
554562 *
563+ * Check req.user.roles for user roles[].
564+ *
555565 * @param roles - List of roles that can access this route
556566 * @returns Method decorator
557567 *
@@ -565,9 +575,15 @@ export function After(fn: Function): MethodDecorator {
565575 * }
566576 * ```
567577 */
568- export function Roles ( ...roles : string [ ] ) : MethodDecorator {
569- return ( target , propertyKey , _descriptor ) => {
570- Reflect . defineMetadata ( ROLES_KEY , roles , target , propertyKey as string ) ;
578+ export function Roles ( ...roles : string [ ] ) : MethodDecorator & ClassDecorator {
579+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
580+ if ( typeof propertyKey === 'undefined' ) {
581+ // Class decorator
582+ Reflect . defineMetadata ( ROLES_KEY , roles , target ) ;
583+ } else {
584+ // Method decorator
585+ Reflect . defineMetadata ( ROLES_KEY , roles , target , propertyKey as string ) ;
586+ }
571587 } ;
572588}
573589
@@ -617,9 +633,15 @@ export function Redirect(url?: string, statusCode: number = 302): MethodDecorato
617633 * }
618634 * ```
619635 */
620- export function Cache ( ttlSeconds : number ) : MethodDecorator {
621- return ( target , propertyKey , _descriptor ) => {
622- Reflect . defineMetadata ( CACHE_KEY , { ttlSeconds } , target , propertyKey as string ) ;
636+ export function Cache ( ttlSeconds : number ) : MethodDecorator & ClassDecorator {
637+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
638+ if ( typeof propertyKey === 'undefined' ) {
639+ // Class decorator
640+ Reflect . defineMetadata ( CACHE_KEY , { ttlSeconds } , target ) ;
641+ } else {
642+ // Method decorator
643+ Reflect . defineMetadata ( CACHE_KEY , { ttlSeconds } , target , propertyKey as string ) ;
644+ }
623645 } ;
624646}
625647
@@ -649,14 +671,20 @@ export function RateLimit(options: {
649671 windowMs : number ;
650672 standardHeaders ?: boolean ;
651673 legacyHeaders ?: boolean ;
652- } ) : MethodDecorator {
674+ } ) : MethodDecorator & ClassDecorator {
653675 const opts = {
654676 standardHeaders : true ,
655677 legacyHeaders : false ,
656678 ...options
657679 } ;
658- return ( target , propertyKey , _descriptor ) => {
659- Reflect . defineMetadata ( RATE_LIMIT_KEY , opts , target , propertyKey as string ) ;
680+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
681+ if ( typeof propertyKey === 'undefined' ) {
682+ // Class decorator
683+ Reflect . defineMetadata ( RATE_LIMIT_KEY , opts , target ) ;
684+ } else {
685+ // Method decorator
686+ Reflect . defineMetadata ( RATE_LIMIT_KEY , opts , target , propertyKey as string ) ;
687+ }
660688 } ;
661689}
662690
@@ -713,16 +741,22 @@ export function ContentType(type: string): MethodDecorator {
713741export function Version (
714742 version : string ,
715743 options ?: { addPrefix ?: boolean ; addHeader ?: boolean ; headerName ?: string }
716- ) : MethodDecorator {
744+ ) : MethodDecorator & ClassDecorator {
717745 const opts = {
718746 addPrefix : true ,
719747 addHeader : true ,
720748 headerName : 'X-API-Version' ,
721749 ...options
722750 } ;
723751
724- return ( target , propertyKey , _descriptor ) => {
725- Reflect . defineMetadata ( VERSION_KEY , { version, options : opts } , target , propertyKey as string ) ;
752+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
753+ if ( typeof propertyKey === 'undefined' ) {
754+ // Class decorator
755+ Reflect . defineMetadata ( VERSION_KEY , { version, options : opts } , target ) ;
756+ } else {
757+ // Method decorator
758+ Reflect . defineMetadata ( VERSION_KEY , { version, options : opts } , target , propertyKey as string ) ;
759+ }
726760 } ;
727761}
728762
@@ -741,9 +775,15 @@ export function Version(
741775 * }
742776 * ```
743777 */
744- export function Timeout ( ms : number ) : MethodDecorator {
745- return ( target , propertyKey , _descriptor ) => {
746- Reflect . defineMetadata ( TIMEOUT_KEY , { ms } , target , propertyKey as string ) ;
778+ export function Timeout ( ms : number ) : MethodDecorator & ClassDecorator {
779+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
780+ if ( typeof propertyKey === 'undefined' ) {
781+ // Class decorator
782+ Reflect . defineMetadata ( TIMEOUT_KEY , { ms } , target ) ;
783+ } else {
784+ // Method decorator
785+ Reflect . defineMetadata ( TIMEOUT_KEY , { ms } , target , propertyKey as string ) ;
786+ }
747787 } ;
748788}
749789
@@ -781,8 +821,8 @@ export function Log(options?: {
781821 logBody ?: boolean ;
782822 logParams ?: boolean ;
783823 logResponse ?: boolean ;
784- } ) : MethodDecorator {
785- return ( target , propertyKey , _descriptor ) => {
824+ } ) : MethodDecorator & ClassDecorator {
825+ return ( target : any , propertyKey ?: string | symbol , _descriptor ?: PropertyDescriptor ) => {
786826 const config = {
787827 logEntry : true ,
788828 logExit : true ,
@@ -791,7 +831,13 @@ export function Log(options?: {
791831 logResponse : false ,
792832 ...options
793833 } ;
794- Reflect . defineMetadata ( LOG_KEY , config , target , propertyKey as string ) ;
834+ if ( typeof propertyKey === 'undefined' ) {
835+ // Class decorator
836+ Reflect . defineMetadata ( LOG_KEY , config , target ) ;
837+ } else {
838+ // Method decorator
839+ Reflect . defineMetadata ( LOG_KEY , config , target , propertyKey as string ) ;
840+ }
795841 } ;
796842}
797843
0 commit comments