@hemia/common 0.0.2 → 0.0.4

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.
Files changed (27) hide show
  1. package/dist/hemia-common.esm.js +89 -2
  2. package/dist/hemia-common.js +93 -1
  3. package/dist/types/decorators/auth/index.d.ts +2 -0
  4. package/dist/types/decorators/auth/permissions.decorator.d.ts +5 -0
  5. package/dist/types/decorators/auth/roles.decorator.d.ts +5 -0
  6. package/dist/types/decorators/core/index.d.ts +4 -0
  7. package/dist/types/decorators/core/serialize.decorator.d.ts +9 -0
  8. package/dist/types/decorators/core/set-metadata.decorator.d.ts +7 -0
  9. package/dist/types/decorators/core/use-guards.decorator.d.ts +7 -0
  10. package/dist/types/decorators/core/use-interceptors.decorator.d.ts +7 -0
  11. package/dist/types/decorators/index.d.ts +2 -1
  12. package/dist/types/decorators/metadata.d.ts +6 -0
  13. package/dist/types/decorators/utils/extend-metadata.util.d.ts +2 -0
  14. package/dist/types/interfaces/activate.interface.d.ts +4 -0
  15. package/dist/types/interfaces/api-response.interface.d.ts +13 -0
  16. package/dist/types/interfaces/features/arguments-host.interface.d.ts +18 -0
  17. package/dist/types/interfaces/features/execution-context.interface.d.ts +14 -0
  18. package/dist/types/interfaces/handler.interface.d.ts +3 -0
  19. package/dist/types/interfaces/index.d.ts +7 -0
  20. package/dist/types/interfaces/interceptor.interface.d.ts +5 -0
  21. package/dist/types/interfaces/type.interface.d.ts +1 -0
  22. package/package.json +1 -1
  23. /package/dist/types/decorators/{controllers → http}/controller.decorator.d.ts +0 -0
  24. /package/dist/types/decorators/{controllers → http}/index.d.ts +0 -0
  25. /package/dist/types/decorators/{controllers → http}/method.decorators.d.ts +0 -0
  26. /package/dist/types/decorators/{controllers → http}/param.decorators.d.ts +0 -0
  27. /package/dist/types/decorators/{controllers → http}/response.decorators.d.ts +0 -0
@@ -5,7 +5,13 @@ const METADATA_KEYS = {
5
5
  ROUTES: 'routes',
6
6
  PARAMS: 'params',
7
7
  HEADERS: 'headers',
8
- REDIRECT: 'redirect'
8
+ REDIRECT: 'redirect',
9
+ GUARDS: 'hemia:guards',
10
+ INTERCEPTORS: 'hemia:interceptors',
11
+ CUSTOM: 'hemia:custom',
12
+ SERIALIZE: 'hemia:serialize',
13
+ ROLES: 'hemia:roles',
14
+ PERMISSIONS: 'hemia:permissions'
9
15
  };
10
16
 
11
17
  const Controller = (basePath = '/') => {
@@ -94,6 +100,87 @@ const Redirect = (url, statusCode = 302) => {
94
100
  };
95
101
  };
96
102
 
103
+ function extendArrayMetadata(key, metadata, target) {
104
+ const previousValue = Reflect.getMetadata(key, target) || [];
105
+ const value = [...previousValue, ...metadata];
106
+ Reflect.defineMetadata(key, value, target);
107
+ }
108
+
109
+ /**
110
+ * Decorador que vincula Guards al controlador o método.
111
+ * @param guards Una lista de clases Guard o instancias de Guard.
112
+ */
113
+ function UseGuards(...guards) {
114
+ return (target, key, descriptor) => {
115
+ guards.filter(guard => guard && (typeof guard === 'function' || typeof guard === 'object'));
116
+ if (descriptor) {
117
+ extendArrayMetadata(METADATA_KEYS.GUARDS, guards, descriptor.value);
118
+ return descriptor;
119
+ }
120
+ extendArrayMetadata(METADATA_KEYS.GUARDS, guards, target);
121
+ return target;
122
+ };
123
+ }
124
+
125
+ /**
126
+ * Decorador que vincula Interceptores al controlador o método.
127
+ * @param interceptors Una lista de clases Interceptor o instancias.
128
+ */
129
+ function UseInterceptors(...interceptors) {
130
+ return (target, key, descriptor) => {
131
+ const validInterceptors = interceptors.filter(i => i && (typeof i === 'function' || typeof i === 'object'));
132
+ if (descriptor) {
133
+ extendArrayMetadata(METADATA_KEYS.INTERCEPTORS, validInterceptors, descriptor.value);
134
+ return descriptor;
135
+ }
136
+ extendArrayMetadata(METADATA_KEYS.INTERCEPTORS, validInterceptors, target);
137
+ return target;
138
+ };
139
+ }
140
+
141
+ /**
142
+ * Decorador que asigna metadata personalizada a una clase o método.
143
+ * @param metadataKey La clave para guardar la metadata (string, symbol, etc.)
144
+ * @param metadataValue El valor a guardar (objeto, array, primitivo, etc.)
145
+ */
146
+ const SetMetadata = (metadataKey, metadataValue) => {
147
+ return (target, key, descriptor) => {
148
+ if (descriptor) {
149
+ Reflect.defineMetadata(metadataKey, metadataValue, descriptor.value);
150
+ return descriptor;
151
+ }
152
+ Reflect.defineMetadata(metadataKey, metadataValue, target);
153
+ return target;
154
+ };
155
+ };
156
+
157
+ /**
158
+ * Decorador que transforma la respuesta saliente a una instancia del DTO proporcionado.
159
+ * @param dto La clase DTO a la que quieres convertir la respuesta.
160
+ */
161
+ function Serialize(dto) {
162
+ return SetMetadata(METADATA_KEYS.SERIALIZE, dto);
163
+ }
164
+
165
+ class ApiResponse {
166
+ static success(data, message = 'OK', status = 200) {
167
+ return {
168
+ success: true,
169
+ message,
170
+ data,
171
+ status,
172
+ };
173
+ }
174
+ static error(message, error = null, status = 500) {
175
+ return {
176
+ success: false,
177
+ message,
178
+ error,
179
+ status,
180
+ };
181
+ }
182
+ }
183
+
97
184
  function isRedirectResponse(value) {
98
185
  return value && typeof value === 'object' && typeof value.url === 'string';
99
186
  }
@@ -163,4 +250,4 @@ class HttpErrorWithDetails extends HttpError {
163
250
  }
164
251
  }
165
252
 
166
- export { BadRequestError, Body, ConflictError, Controller, CustomHttpError, Delete, ForbiddenError, GatewayTimeoutError, Get, Head, Header, Headers, Host, HttpError, HttpErrorWithDetails, HttpMethod, InternalServerError, Ip, METADATA_KEYS, Next, NotFoundError, Options, Param, ParamType, Patch, Post, Put, Query, Redirect, Req, Request, Res, Response, ServiceUnavailableError, Session, UnauthorizedError, UnprocessableEntityError, isRedirectResponse };
253
+ export { ApiResponse, BadRequestError, Body, ConflictError, Controller, CustomHttpError, Delete, ForbiddenError, GatewayTimeoutError, Get, Head, Header, Headers, Host, HttpError, HttpErrorWithDetails, HttpMethod, InternalServerError, Ip, METADATA_KEYS, Next, NotFoundError, Options, Param, ParamType, Patch, Post, Put, Query, Redirect, Req, Request, Res, Response, Serialize, ServiceUnavailableError, Session, SetMetadata, UnauthorizedError, UnprocessableEntityError, UseGuards, UseInterceptors, isRedirectResponse };
@@ -7,7 +7,13 @@ const METADATA_KEYS = {
7
7
  ROUTES: 'routes',
8
8
  PARAMS: 'params',
9
9
  HEADERS: 'headers',
10
- REDIRECT: 'redirect'
10
+ REDIRECT: 'redirect',
11
+ GUARDS: 'hemia:guards',
12
+ INTERCEPTORS: 'hemia:interceptors',
13
+ CUSTOM: 'hemia:custom',
14
+ SERIALIZE: 'hemia:serialize',
15
+ ROLES: 'hemia:roles',
16
+ PERMISSIONS: 'hemia:permissions'
11
17
  };
12
18
 
13
19
  const Controller = (basePath = '/') => {
@@ -96,6 +102,87 @@ const Redirect = (url, statusCode = 302) => {
96
102
  };
97
103
  };
98
104
 
105
+ function extendArrayMetadata(key, metadata, target) {
106
+ const previousValue = Reflect.getMetadata(key, target) || [];
107
+ const value = [...previousValue, ...metadata];
108
+ Reflect.defineMetadata(key, value, target);
109
+ }
110
+
111
+ /**
112
+ * Decorador que vincula Guards al controlador o método.
113
+ * @param guards Una lista de clases Guard o instancias de Guard.
114
+ */
115
+ function UseGuards(...guards) {
116
+ return (target, key, descriptor) => {
117
+ guards.filter(guard => guard && (typeof guard === 'function' || typeof guard === 'object'));
118
+ if (descriptor) {
119
+ extendArrayMetadata(METADATA_KEYS.GUARDS, guards, descriptor.value);
120
+ return descriptor;
121
+ }
122
+ extendArrayMetadata(METADATA_KEYS.GUARDS, guards, target);
123
+ return target;
124
+ };
125
+ }
126
+
127
+ /**
128
+ * Decorador que vincula Interceptores al controlador o método.
129
+ * @param interceptors Una lista de clases Interceptor o instancias.
130
+ */
131
+ function UseInterceptors(...interceptors) {
132
+ return (target, key, descriptor) => {
133
+ const validInterceptors = interceptors.filter(i => i && (typeof i === 'function' || typeof i === 'object'));
134
+ if (descriptor) {
135
+ extendArrayMetadata(METADATA_KEYS.INTERCEPTORS, validInterceptors, descriptor.value);
136
+ return descriptor;
137
+ }
138
+ extendArrayMetadata(METADATA_KEYS.INTERCEPTORS, validInterceptors, target);
139
+ return target;
140
+ };
141
+ }
142
+
143
+ /**
144
+ * Decorador que asigna metadata personalizada a una clase o método.
145
+ * @param metadataKey La clave para guardar la metadata (string, symbol, etc.)
146
+ * @param metadataValue El valor a guardar (objeto, array, primitivo, etc.)
147
+ */
148
+ const SetMetadata = (metadataKey, metadataValue) => {
149
+ return (target, key, descriptor) => {
150
+ if (descriptor) {
151
+ Reflect.defineMetadata(metadataKey, metadataValue, descriptor.value);
152
+ return descriptor;
153
+ }
154
+ Reflect.defineMetadata(metadataKey, metadataValue, target);
155
+ return target;
156
+ };
157
+ };
158
+
159
+ /**
160
+ * Decorador que transforma la respuesta saliente a una instancia del DTO proporcionado.
161
+ * @param dto La clase DTO a la que quieres convertir la respuesta.
162
+ */
163
+ function Serialize(dto) {
164
+ return SetMetadata(METADATA_KEYS.SERIALIZE, dto);
165
+ }
166
+
167
+ class ApiResponse {
168
+ static success(data, message = 'OK', status = 200) {
169
+ return {
170
+ success: true,
171
+ message,
172
+ data,
173
+ status,
174
+ };
175
+ }
176
+ static error(message, error = null, status = 500) {
177
+ return {
178
+ success: false,
179
+ message,
180
+ error,
181
+ status,
182
+ };
183
+ }
184
+ }
185
+
99
186
  function isRedirectResponse(value) {
100
187
  return value && typeof value === 'object' && typeof value.url === 'string';
101
188
  }
@@ -165,6 +252,7 @@ class HttpErrorWithDetails extends HttpError {
165
252
  }
166
253
  }
167
254
 
255
+ exports.ApiResponse = ApiResponse;
168
256
  exports.BadRequestError = BadRequestError;
169
257
  exports.Body = Body;
170
258
  exports.ConflictError = ConflictError;
@@ -196,8 +284,12 @@ exports.Req = Req;
196
284
  exports.Request = Request;
197
285
  exports.Res = Res;
198
286
  exports.Response = Response;
287
+ exports.Serialize = Serialize;
199
288
  exports.ServiceUnavailableError = ServiceUnavailableError;
200
289
  exports.Session = Session;
290
+ exports.SetMetadata = SetMetadata;
201
291
  exports.UnauthorizedError = UnauthorizedError;
202
292
  exports.UnprocessableEntityError = UnprocessableEntityError;
293
+ exports.UseGuards = UseGuards;
294
+ exports.UseInterceptors = UseInterceptors;
203
295
  exports.isRedirectResponse = isRedirectResponse;
@@ -0,0 +1,2 @@
1
+ export * from './roles.decorator';
2
+ export * from './permissions.decorator';
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Define los permisos específicos requeridos para acceder a un recurso.
3
+ * @param permissions Lista de permisos (ej: 'read:users', 'write:posts')
4
+ */
5
+ export declare const Permissions: (...permissions: string[]) => (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Define los roles requeridos para acceder a un recurso.
3
+ * @param roles Lista de roles (ej: 'admin', 'user')
4
+ */
5
+ export declare const Roles: (...roles: string[]) => (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -0,0 +1,4 @@
1
+ export * from "./use-guards.decorator";
2
+ export * from "./use-interceptors.decorator";
3
+ export * from "./set-metadata.decorator";
4
+ export * from "./serialize.decorator";
@@ -0,0 +1,9 @@
1
+ import { Type } from "../../interfaces";
2
+ export interface SerializeOptions {
3
+ excludeExtraneousValues?: boolean;
4
+ }
5
+ /**
6
+ * Decorador que transforma la respuesta saliente a una instancia del DTO proporcionado.
7
+ * @param dto La clase DTO a la que quieres convertir la respuesta.
8
+ */
9
+ export declare function Serialize(dto: Type<any>): (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -0,0 +1,7 @@
1
+ import 'reflect-metadata';
2
+ /**
3
+ * Decorador que asigna metadata personalizada a una clase o método.
4
+ * @param metadataKey La clave para guardar la metadata (string, symbol, etc.)
5
+ * @param metadataValue El valor a guardar (objeto, array, primitivo, etc.)
6
+ */
7
+ export declare const SetMetadata: <K = string | symbol, V = any>(metadataKey: K, metadataValue: V) => (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -0,0 +1,7 @@
1
+ import 'reflect-metadata';
2
+ import { CanActivate, Type } from '../../interfaces';
3
+ /**
4
+ * Decorador que vincula Guards al controlador o método.
5
+ * @param guards Una lista de clases Guard o instancias de Guard.
6
+ */
7
+ export declare function UseGuards(...guards: (Type<CanActivate> | CanActivate | Function)[]): (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -0,0 +1,7 @@
1
+ import 'reflect-metadata';
2
+ import { HemiaInterceptor, Type } from '../../interfaces';
3
+ /**
4
+ * Decorador que vincula Interceptores al controlador o método.
5
+ * @param interceptors Una lista de clases Interceptor o instancias.
6
+ */
7
+ export declare function UseInterceptors(...interceptors: (Type<HemiaInterceptor> | HemiaInterceptor | Function)[]): (target: object | Function, key?: string | symbol, descriptor?: PropertyDescriptor) => object;
@@ -1,2 +1,3 @@
1
- export * from "./controllers";
1
+ export * from "./http";
2
2
  export * from "./metadata";
3
+ export * from "./core";
@@ -4,4 +4,10 @@ export declare const METADATA_KEYS: {
4
4
  readonly PARAMS: "params";
5
5
  readonly HEADERS: "headers";
6
6
  readonly REDIRECT: "redirect";
7
+ readonly GUARDS: "hemia:guards";
8
+ readonly INTERCEPTORS: "hemia:interceptors";
9
+ readonly CUSTOM: "hemia:custom";
10
+ readonly SERIALIZE: "hemia:serialize";
11
+ readonly ROLES: "hemia:roles";
12
+ readonly PERMISSIONS: "hemia:permissions";
7
13
  };
@@ -0,0 +1,2 @@
1
+ import 'reflect-metadata';
2
+ export declare function extendArrayMetadata<T>(key: string, metadata: T[], target: object | Function): void;
@@ -0,0 +1,4 @@
1
+ import { ExecutionContext } from "./features/execution-context.interface";
2
+ export interface CanActivate {
3
+ canActivate(context: ExecutionContext): boolean | Promise<boolean>;
4
+ }
@@ -0,0 +1,13 @@
1
+ export interface IResponseData<T> {
2
+ success: boolean;
3
+ data?: T;
4
+ message: string;
5
+ error?: any;
6
+ }
7
+ export interface IApiResponse<T> extends IResponseData<T> {
8
+ status: number;
9
+ }
10
+ export declare class ApiResponse {
11
+ static success<T>(data: T, message?: string, status?: number): IApiResponse<T>;
12
+ static error(message: string, error?: any, status?: number): IApiResponse<null>;
13
+ }
@@ -0,0 +1,18 @@
1
+ export interface HttpArgumentsHost {
2
+ /** Retorna el objeto Request nativo (Express) */
3
+ getRequest<T = any>(): T;
4
+ /** Retorna el objeto Response nativo (Express) */
5
+ getResponse<T = any>(): T;
6
+ /** Retorna la función Next nativa (Express) */
7
+ getNext<T = any>(): T;
8
+ }
9
+ export interface ArgumentsHost {
10
+ /** Retorna el array de argumentos original [req, res, next] */
11
+ getArgs<T extends Array<any> = any[]>(): T;
12
+ /** Retorna un argumento específico por índice */
13
+ getArgByIndex<T = any>(index: number): T;
14
+ /** Cambia el contexto a HTTP para obtener métodos tipados */
15
+ switchToHttp(): HttpArgumentsHost;
16
+ /** Retorna el tipo de contexto actual (ej: 'http') */
17
+ getType<TContext extends string = string>(): TContext;
18
+ }
@@ -0,0 +1,14 @@
1
+ import { Type } from "../type.interface";
2
+ import { ArgumentsHost } from "./arguments-host.interface";
3
+ export interface ExecutionContext extends ArgumentsHost {
4
+ /**
5
+ * Retorna la CLASE (Constructor) del controlador que se está ejecutando.
6
+ * Útil para leer metadata a nivel de clase (ej. @Roles('admin') sobre la clase)
7
+ */
8
+ getClass<T = any>(): Type<T>;
9
+ /**
10
+ * Retorna la FUNCIÓN (Método) del handler que se está ejecutando.
11
+ * Útil para leer metadata a nivel de método (ej. @Public() sobre el método)
12
+ */
13
+ getHandler(): Function;
14
+ }
@@ -0,0 +1,3 @@
1
+ export interface CallHandler<T = any> {
2
+ handle(): Promise<T>;
3
+ }
@@ -1,2 +1,9 @@
1
1
  export * from './param.interface';
2
2
  export * from './route.interface';
3
+ export * from './api-response.interface';
4
+ export * from './activate.interface';
5
+ export * from './features/execution-context.interface';
6
+ export * from "./features/arguments-host.interface";
7
+ export * from './type.interface';
8
+ export * from './handler.interface';
9
+ export * from './interceptor.interface';
@@ -0,0 +1,5 @@
1
+ import { ExecutionContext } from "./features/execution-context.interface";
2
+ import { CallHandler } from "./handler.interface";
3
+ export interface HemiaInterceptor<T = any, R = any> {
4
+ intercept(context: ExecutionContext, next: CallHandler<T>): Promise<R>;
5
+ }
@@ -0,0 +1 @@
1
+ export type Type<T = any> = new (...args: any[]) => T;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hemia/common",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Paquete común para proyectos de Hemia",
5
5
  "main": "dist/hemia-common.js",
6
6
  "module": "dist/hemia-common.esm.js",