@hemia/core 0.0.3 → 0.0.5

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.
@@ -1,10 +1,12 @@
1
1
  import 'reflect-metadata';
2
2
  import express, { Router } from 'express';
3
- import { METADATA_KEYS, ParamType, isRedirectResponse, ApiResponse } from '@hemia/common';
3
+ import { METADATA_KEYS, ParamType, ApiResponse, isRedirectResponse } from '@hemia/common';
4
4
  import { TRACE_METADATA_KEY } from '@hemia/trace-manager';
5
5
  import { traceMiddleware } from '@hemia/app-context';
6
6
  import { plainToInstance } from 'class-transformer';
7
- import { injectable } from 'inversify';
7
+ import multer from 'multer';
8
+ import { injectable, inject } from 'inversify';
9
+ import { AUTH_SERVICE_ID, AuthService } from '@hemia/auth-sdk';
8
10
 
9
11
  class GuardsConsumer {
10
12
  /**
@@ -79,7 +81,7 @@ class ResponseSerializer {
79
81
  * @param container Instancia del Container de Inversify
80
82
  * @param controllerIdentifiers Array de Symbols (o Clases si usas self-binding)
81
83
  */
82
- async function registerRoutes(app, container, controllerIdentifiers, onTraceFinishCallback) {
84
+ async function registerRoutes(app, container, controllerIdentifiers, onTraceFinishCallback, multerOptions) {
83
85
  for (const identifier of controllerIdentifiers) {
84
86
  const instance = await container.getAsync(identifier);
85
87
  const prototype = Object.getPrototypeOf(instance);
@@ -101,6 +103,14 @@ async function registerRoutes(app, container, controllerIdentifiers, onTraceFini
101
103
  // Leer metadata de headers y redirect
102
104
  const headersMetadata = Reflect.getMetadata(METADATA_KEYS.HEADERS, ControllerClass, route.methodName) || [];
103
105
  const redirectMetadata = Reflect.getMetadata(METADATA_KEYS.REDIRECT, ControllerClass, route.methodName);
106
+ const needsFile = paramsMetadata.some(p => p.type === ParamType.FILE);
107
+ const needsFiles = paramsMetadata.some(p => p.type === ParamType.FILES);
108
+ if (needsFiles) {
109
+ handlers.push(multer(multerOptions).array('files'));
110
+ }
111
+ else if (needsFile) {
112
+ handlers.push(multer(multerOptions).single('file'));
113
+ }
104
114
  const mainHandler = async (req, res, next) => {
105
115
  try {
106
116
  const args = [];
@@ -137,11 +147,59 @@ async function registerRoutes(app, container, controllerIdentifiers, onTraceFini
137
147
  case ParamType.SESSION:
138
148
  args[param.index] = req.session;
139
149
  break;
150
+ case ParamType.COOKIES:
151
+ args[param.index] = param.data ? req.cookies?.[param.data] : req.cookies;
152
+ break;
153
+ case ParamType.FILE:
154
+ args[param.index] = req.file;
155
+ break;
156
+ case ParamType.FILES:
157
+ args[param.index] = req.files;
158
+ break;
159
+ case ParamType.USER:
160
+ args[param.index] = req.user;
161
+ break;
162
+ case ParamType.IP:
163
+ args[param.index] = req.ip;
164
+ break;
165
+ case ParamType.LOCALE:
166
+ args[param.index] = req.acceptsLanguages()[0];
167
+ break;
168
+ case ParamType.HOST:
169
+ args[param.index] = req.hostname;
170
+ break;
171
+ case ParamType.PERMISSIONS:
172
+ args[param.index] = req.permissions;
173
+ break;
174
+ case ParamType.CONTEXT:
175
+ args[param.index] = req.context;
176
+ break;
140
177
  default: args[param.index] = undefined;
141
178
  }
142
179
  });
143
180
  }
181
+ // CUSTOM PARAMETERS
182
+ const customs = Reflect.getMetadata(METADATA_KEYS.CUSTOMS, instance, route.methodName) || [];
183
+ for (const { index, key } of customs) {
184
+ args[index] = req.customData?.[key];
185
+ }
186
+ // TRANSFORMACIÓN DE PARÁMETROS
187
+ const transformers = Reflect.getMetadata(METADATA_KEYS.TRANSFORMERS, instance, route.methodName) || [];
188
+ for (const { index, transformer } of transformers) {
189
+ args[index] = transformer(args[index]);
190
+ }
191
+ // VALIDACIÓN DE PARÁMETROS
192
+ const validators = Reflect.getMetadata(METADATA_KEYS.VALIDATORS, instance, route.methodName) || [];
193
+ for (const { index, validator } of validators) {
194
+ const value = args[index];
195
+ const result = validator(value);
196
+ if (result === false) {
197
+ return res.status(400).json(ApiResponse.error('Validation failed', undefined, 400));
198
+ }
199
+ }
200
+ // EJECUCIÓN DEL CONTROLLER
144
201
  const result = await instance[route.methodName](...args);
202
+ // SERIALIZACIÓN DE RESULTADO
145
203
  const serializeDto = Reflect.getMetadata(METADATA_KEYS.SERIALIZE, methodHandler) || Reflect.getMetadata(METADATA_KEYS.SERIALIZE, ControllerClass);
146
204
  let finalResult = result;
147
205
  if (serializeDto) {
@@ -206,6 +264,10 @@ function __decorate(decorators, target, key, desc) {
206
264
  return c > 3 && r && Object.defineProperty(target, key, r), r;
207
265
  }
208
266
 
267
+ function __param(paramIndex, decorator) {
268
+ return function (target, key) { decorator(target, key, paramIndex); }
269
+ }
270
+
209
271
  function __metadata(metadataKey, metadataValue) {
210
272
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
211
273
  }
@@ -259,8 +321,8 @@ class HemiaFactory {
259
321
  */
260
322
  static async create(container, controllers, options = {}) {
261
323
  const app = express();
262
- app.use(express.json());
263
- app.use(express.urlencoded({ extended: true }));
324
+ app.use(express.json(options.jsonOptions));
325
+ app.use(express.urlencoded({ extended: true, ...options.urlencodedOptions }));
264
326
  if (options.middlewares && Array.isArray(options.middlewares)) {
265
327
  options.middlewares.forEach(middleware => {
266
328
  app.use(middleware);
@@ -291,7 +353,14 @@ class HemiaFactory {
291
353
  container.bind(controllerClass).toSelf();
292
354
  }
293
355
  });
294
- await registerRoutes(app, container, controllers, options.onTraceFinish || (() => { }));
356
+ await registerRoutes(app, container, controllers, options.onTraceFinish || (() => { }), options.multerOptions);
357
+ app.use((err, req, res, next) => {
358
+ console.error('[Hemia] Unhandled error:', err);
359
+ res.status(err.status || 500).json({
360
+ error: err.message || 'Internal Server Error',
361
+ details: err.details || undefined,
362
+ });
363
+ });
295
364
  if (options.logger !== false) {
296
365
  console.log(`[Hemia] Application initialized with ${controllers.length} controllers.`);
297
366
  }
@@ -299,6 +368,10 @@ class HemiaFactory {
299
368
  }
300
369
  }
301
370
 
371
+ /**
372
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
373
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
374
+ */
302
375
  let AuthGuard = class AuthGuard {
303
376
  constructor(reflector) {
304
377
  this.reflector = reflector;
@@ -315,17 +388,19 @@ let AuthGuard = class AuthGuard {
315
388
  }
316
389
  const request = context.switchToHttp().getRequest();
317
390
  const user = request.user;
318
- if (!user || !user.roles) {
391
+ const permissions = request.permissions;
392
+ const contextData = request.context;
393
+ if (!user) {
319
394
  return false;
320
395
  }
321
396
  if (requiredRoles) {
322
- const userRoleNames = user.roles.map((r) => r.name);
397
+ const userRoleNames = Array.isArray(contextData.roles) ? contextData.roles : [];
323
398
  const hasRole = requiredRoles.some((role) => userRoleNames.includes(role));
324
399
  if (!hasRole)
325
400
  return false;
326
401
  }
327
402
  if (requiredPermissions) {
328
- const userPermissions = user.roles.flatMap((r) => r.permissions || []);
403
+ const userPermissions = Array.isArray(permissions) ? permissions : [];
329
404
  const hasPermission = requiredPermissions.some((perm) => userPermissions.includes(perm));
330
405
  if (!hasPermission)
331
406
  return false;
@@ -338,4 +413,66 @@ AuthGuard = __decorate([
338
413
  __metadata("design:paramtypes", [Reflector])
339
414
  ], AuthGuard);
340
415
 
341
- export { AuthGuard, GuardsConsumer, HemiaExecutionContext, HemiaFactory, Reflector, ResponseSerializer, registerRoutes };
416
+ /**
417
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
418
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
419
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
420
+ */
421
+ let ApiKeyGuard = class ApiKeyGuard {
422
+ constructor() {
423
+ this.validApiKeys = (process.env.API_KEY || "")
424
+ .split(",")
425
+ .map(key => key.trim())
426
+ .filter(key => !!key);
427
+ }
428
+ canActivate(context) {
429
+ const request = context.switchToHttp().getRequest();
430
+ const apiKey = request.headers['x-api-key'] || request.query['api_key'];
431
+ if (!apiKey)
432
+ return false;
433
+ return this.validApiKeys.includes(apiKey);
434
+ }
435
+ };
436
+ ApiKeyGuard = __decorate([
437
+ injectable(),
438
+ __metadata("design:paramtypes", [])
439
+ ], ApiKeyGuard);
440
+
441
+ /**
442
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
443
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
444
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
445
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
446
+ */
447
+ let JWTGuard = class JWTGuard {
448
+ constructor(authService) {
449
+ this.authService = authService;
450
+ }
451
+ async canActivate(context) {
452
+ const request = context.switchToHttp().getRequest();
453
+ const sessionId = request.headers['x-session'] || request.cookies['x-session'];
454
+ if (!sessionId) {
455
+ return false;
456
+ }
457
+ try {
458
+ const accessTokenData = await this.authService.getSessionAccess(sessionId);
459
+ if (!accessTokenData) {
460
+ return false;
461
+ }
462
+ request.user = accessTokenData.user;
463
+ request.permissions = accessTokenData.permissions;
464
+ request.context = accessTokenData.context;
465
+ return true;
466
+ }
467
+ catch (error) {
468
+ return false;
469
+ }
470
+ }
471
+ };
472
+ JWTGuard = __decorate([
473
+ injectable(),
474
+ __param(0, inject(AUTH_SERVICE_ID)),
475
+ __metadata("design:paramtypes", [AuthService])
476
+ ], JWTGuard);
477
+
478
+ export { ApiKeyGuard, AuthGuard, GuardsConsumer, HemiaExecutionContext, HemiaFactory, JWTGuard, Reflector, ResponseSerializer, registerRoutes };
@@ -6,7 +6,9 @@ var common = require('@hemia/common');
6
6
  var traceManager = require('@hemia/trace-manager');
7
7
  var appContext = require('@hemia/app-context');
8
8
  var classTransformer = require('class-transformer');
9
+ var multer = require('multer');
9
10
  var inversify = require('inversify');
11
+ var authSdk = require('@hemia/auth-sdk');
10
12
 
11
13
  class GuardsConsumer {
12
14
  /**
@@ -81,7 +83,7 @@ class ResponseSerializer {
81
83
  * @param container Instancia del Container de Inversify
82
84
  * @param controllerIdentifiers Array de Symbols (o Clases si usas self-binding)
83
85
  */
84
- async function registerRoutes(app, container, controllerIdentifiers, onTraceFinishCallback) {
86
+ async function registerRoutes(app, container, controllerIdentifiers, onTraceFinishCallback, multerOptions) {
85
87
  for (const identifier of controllerIdentifiers) {
86
88
  const instance = await container.getAsync(identifier);
87
89
  const prototype = Object.getPrototypeOf(instance);
@@ -103,6 +105,14 @@ async function registerRoutes(app, container, controllerIdentifiers, onTraceFini
103
105
  // Leer metadata de headers y redirect
104
106
  const headersMetadata = Reflect.getMetadata(common.METADATA_KEYS.HEADERS, ControllerClass, route.methodName) || [];
105
107
  const redirectMetadata = Reflect.getMetadata(common.METADATA_KEYS.REDIRECT, ControllerClass, route.methodName);
108
+ const needsFile = paramsMetadata.some(p => p.type === common.ParamType.FILE);
109
+ const needsFiles = paramsMetadata.some(p => p.type === common.ParamType.FILES);
110
+ if (needsFiles) {
111
+ handlers.push(multer(multerOptions).array('files'));
112
+ }
113
+ else if (needsFile) {
114
+ handlers.push(multer(multerOptions).single('file'));
115
+ }
106
116
  const mainHandler = async (req, res, next) => {
107
117
  try {
108
118
  const args = [];
@@ -139,11 +149,59 @@ async function registerRoutes(app, container, controllerIdentifiers, onTraceFini
139
149
  case common.ParamType.SESSION:
140
150
  args[param.index] = req.session;
141
151
  break;
152
+ case common.ParamType.COOKIES:
153
+ args[param.index] = param.data ? req.cookies?.[param.data] : req.cookies;
154
+ break;
155
+ case common.ParamType.FILE:
156
+ args[param.index] = req.file;
157
+ break;
158
+ case common.ParamType.FILES:
159
+ args[param.index] = req.files;
160
+ break;
161
+ case common.ParamType.USER:
162
+ args[param.index] = req.user;
163
+ break;
164
+ case common.ParamType.IP:
165
+ args[param.index] = req.ip;
166
+ break;
167
+ case common.ParamType.LOCALE:
168
+ args[param.index] = req.acceptsLanguages()[0];
169
+ break;
170
+ case common.ParamType.HOST:
171
+ args[param.index] = req.hostname;
172
+ break;
173
+ case common.ParamType.PERMISSIONS:
174
+ args[param.index] = req.permissions;
175
+ break;
176
+ case common.ParamType.CONTEXT:
177
+ args[param.index] = req.context;
178
+ break;
142
179
  default: args[param.index] = undefined;
143
180
  }
144
181
  });
145
182
  }
183
+ // CUSTOM PARAMETERS
184
+ const customs = Reflect.getMetadata(common.METADATA_KEYS.CUSTOMS, instance, route.methodName) || [];
185
+ for (const { index, key } of customs) {
186
+ args[index] = req.customData?.[key];
187
+ }
188
+ // TRANSFORMACIÓN DE PARÁMETROS
189
+ const transformers = Reflect.getMetadata(common.METADATA_KEYS.TRANSFORMERS, instance, route.methodName) || [];
190
+ for (const { index, transformer } of transformers) {
191
+ args[index] = transformer(args[index]);
192
+ }
193
+ // VALIDACIÓN DE PARÁMETROS
194
+ const validators = Reflect.getMetadata(common.METADATA_KEYS.VALIDATORS, instance, route.methodName) || [];
195
+ for (const { index, validator } of validators) {
196
+ const value = args[index];
197
+ const result = validator(value);
198
+ if (result === false) {
199
+ return res.status(400).json(common.ApiResponse.error('Validation failed', undefined, 400));
200
+ }
201
+ }
202
+ // EJECUCIÓN DEL CONTROLLER
146
203
  const result = await instance[route.methodName](...args);
204
+ // SERIALIZACIÓN DE RESULTADO
147
205
  const serializeDto = Reflect.getMetadata(common.METADATA_KEYS.SERIALIZE, methodHandler) || Reflect.getMetadata(common.METADATA_KEYS.SERIALIZE, ControllerClass);
148
206
  let finalResult = result;
149
207
  if (serializeDto) {
@@ -208,6 +266,10 @@ function __decorate(decorators, target, key, desc) {
208
266
  return c > 3 && r && Object.defineProperty(target, key, r), r;
209
267
  }
210
268
 
269
+ function __param(paramIndex, decorator) {
270
+ return function (target, key) { decorator(target, key, paramIndex); }
271
+ }
272
+
211
273
  function __metadata(metadataKey, metadataValue) {
212
274
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
213
275
  }
@@ -261,8 +323,8 @@ class HemiaFactory {
261
323
  */
262
324
  static async create(container, controllers, options = {}) {
263
325
  const app = express();
264
- app.use(express.json());
265
- app.use(express.urlencoded({ extended: true }));
326
+ app.use(express.json(options.jsonOptions));
327
+ app.use(express.urlencoded({ extended: true, ...options.urlencodedOptions }));
266
328
  if (options.middlewares && Array.isArray(options.middlewares)) {
267
329
  options.middlewares.forEach(middleware => {
268
330
  app.use(middleware);
@@ -293,7 +355,14 @@ class HemiaFactory {
293
355
  container.bind(controllerClass).toSelf();
294
356
  }
295
357
  });
296
- await registerRoutes(app, container, controllers, options.onTraceFinish || (() => { }));
358
+ await registerRoutes(app, container, controllers, options.onTraceFinish || (() => { }), options.multerOptions);
359
+ app.use((err, req, res, next) => {
360
+ console.error('[Hemia] Unhandled error:', err);
361
+ res.status(err.status || 500).json({
362
+ error: err.message || 'Internal Server Error',
363
+ details: err.details || undefined,
364
+ });
365
+ });
297
366
  if (options.logger !== false) {
298
367
  console.log(`[Hemia] Application initialized with ${controllers.length} controllers.`);
299
368
  }
@@ -301,6 +370,10 @@ class HemiaFactory {
301
370
  }
302
371
  }
303
372
 
373
+ /**
374
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
375
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
376
+ */
304
377
  exports.AuthGuard = class AuthGuard {
305
378
  constructor(reflector) {
306
379
  this.reflector = reflector;
@@ -317,17 +390,19 @@ exports.AuthGuard = class AuthGuard {
317
390
  }
318
391
  const request = context.switchToHttp().getRequest();
319
392
  const user = request.user;
320
- if (!user || !user.roles) {
393
+ const permissions = request.permissions;
394
+ const contextData = request.context;
395
+ if (!user) {
321
396
  return false;
322
397
  }
323
398
  if (requiredRoles) {
324
- const userRoleNames = user.roles.map((r) => r.name);
399
+ const userRoleNames = Array.isArray(contextData.roles) ? contextData.roles : [];
325
400
  const hasRole = requiredRoles.some((role) => userRoleNames.includes(role));
326
401
  if (!hasRole)
327
402
  return false;
328
403
  }
329
404
  if (requiredPermissions) {
330
- const userPermissions = user.roles.flatMap((r) => r.permissions || []);
405
+ const userPermissions = Array.isArray(permissions) ? permissions : [];
331
406
  const hasPermission = requiredPermissions.some((perm) => userPermissions.includes(perm));
332
407
  if (!hasPermission)
333
408
  return false;
@@ -340,6 +415,68 @@ exports.AuthGuard = __decorate([
340
415
  __metadata("design:paramtypes", [exports.Reflector])
341
416
  ], exports.AuthGuard);
342
417
 
418
+ /**
419
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
420
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
421
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
422
+ */
423
+ exports.ApiKeyGuard = class ApiKeyGuard {
424
+ constructor() {
425
+ this.validApiKeys = (process.env.API_KEY || "")
426
+ .split(",")
427
+ .map(key => key.trim())
428
+ .filter(key => !!key);
429
+ }
430
+ canActivate(context) {
431
+ const request = context.switchToHttp().getRequest();
432
+ const apiKey = request.headers['x-api-key'] || request.query['api_key'];
433
+ if (!apiKey)
434
+ return false;
435
+ return this.validApiKeys.includes(apiKey);
436
+ }
437
+ };
438
+ exports.ApiKeyGuard = __decorate([
439
+ inversify.injectable(),
440
+ __metadata("design:paramtypes", [])
441
+ ], exports.ApiKeyGuard);
442
+
443
+ /**
444
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
445
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
446
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
447
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
448
+ */
449
+ exports.JWTGuard = class JWTGuard {
450
+ constructor(authService) {
451
+ this.authService = authService;
452
+ }
453
+ async canActivate(context) {
454
+ const request = context.switchToHttp().getRequest();
455
+ const sessionId = request.headers['x-session'] || request.cookies['x-session'];
456
+ if (!sessionId) {
457
+ return false;
458
+ }
459
+ try {
460
+ const accessTokenData = await this.authService.getSessionAccess(sessionId);
461
+ if (!accessTokenData) {
462
+ return false;
463
+ }
464
+ request.user = accessTokenData.user;
465
+ request.permissions = accessTokenData.permissions;
466
+ request.context = accessTokenData.context;
467
+ return true;
468
+ }
469
+ catch (error) {
470
+ return false;
471
+ }
472
+ }
473
+ };
474
+ exports.JWTGuard = __decorate([
475
+ inversify.injectable(),
476
+ __param(0, inversify.inject(authSdk.AUTH_SERVICE_ID)),
477
+ __metadata("design:paramtypes", [authSdk.AuthService])
478
+ ], exports.JWTGuard);
479
+
343
480
  exports.GuardsConsumer = GuardsConsumer;
344
481
  exports.HemiaExecutionContext = HemiaExecutionContext;
345
482
  exports.HemiaFactory = HemiaFactory;
@@ -0,0 +1,11 @@
1
+ import { CanActivate, ExecutionContext } from "@hemia/common";
2
+ /**
3
+ * Guardia para validar la presencia y validez de una API Key en las solicitudes entrantes.
4
+ * La API Key se espera en el encabezado 'x-api-key' o como parámetro de consulta 'api_key'.
5
+ * Las claves válidas se configuran mediante la variable de entorno 'API_KEY' y pueden ser múltiples, separadas por comas.
6
+ */
7
+ export declare class ApiKeyGuard implements CanActivate {
8
+ private readonly validApiKeys;
9
+ constructor();
10
+ canActivate(context: ExecutionContext): boolean;
11
+ }
@@ -1,5 +1,9 @@
1
1
  import { CanActivate, ExecutionContext } from '@hemia/common';
2
2
  import { Reflector } from '../services';
3
+ /**
4
+ * Guardia de autorización que verifica roles y permisos definidos en los controladores y métodos.
5
+ * Utiliza los metadatos definidos con los decoradores @Roles y @Permissions.
6
+ */
3
7
  export declare class AuthGuard implements CanActivate {
4
8
  private reflector;
5
9
  constructor(reflector: Reflector);
@@ -1,2 +1,4 @@
1
1
  export * from "./auth.guard";
2
2
  export * from "./guards-consumer";
3
+ export * from "./api-key.guard";
4
+ export * from "./jwt.guard";
@@ -0,0 +1,13 @@
1
+ import { CanActivate, ExecutionContext } from "@hemia/common";
2
+ import { AuthService } from "@hemia/auth-sdk";
3
+ /**
4
+ * Guardia para validar y procesar tokens JWT en las solicitudes entrantes.
5
+ * Extrae el token de sesión del encabezado 'x-session' o de las cookies,
6
+ * y utiliza el AuthService para validar el token y obtener los datos del usuario.
7
+ * Si el token es válido, adjunta la información del usuario, permisos y contexto a la solicitud.
8
+ */
9
+ export declare class JWTGuard implements CanActivate {
10
+ private readonly authService;
11
+ constructor(authService: AuthService);
12
+ canActivate(context: ExecutionContext): Promise<boolean>;
13
+ }
@@ -7,6 +7,9 @@ export interface HemiaFactoryOptions {
7
7
  logger?: boolean;
8
8
  corsHeaders?: Record<string, string>;
9
9
  middlewares?: any[];
10
+ multerOptions?: any;
11
+ jsonOptions?: any;
12
+ urlencodedOptions?: any;
10
13
  }
11
14
  export declare class HemiaFactory {
12
15
  /**
@@ -7,4 +7,4 @@ export type TraceFinishCallback = (payloads: any, context: any, res: Response) =
7
7
  * @param container Instancia del Container de Inversify
8
8
  * @param controllerIdentifiers Array de Symbols (o Clases si usas self-binding)
9
9
  */
10
- export declare function registerRoutes(app: Express, container: Container, controllerIdentifiers: any[], onTraceFinishCallback: TraceFinishCallback): Promise<void>;
10
+ export declare function registerRoutes(app: Express, container: Container, controllerIdentifiers: any[], onTraceFinishCallback: TraceFinishCallback, multerOptions?: any): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hemia/core",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Core utilities for Hemia projects",
5
5
  "main": "dist/hemia-core.js",
6
6
  "module": "dist/hemia-core.esm.js",
@@ -17,15 +17,17 @@
17
17
  "@rollup/plugin-commonjs": "^26.0.1",
18
18
  "@rollup/plugin-json": "^6.1.0",
19
19
  "@rollup/plugin-node-resolve": "^15.2.3",
20
- "@hemia/common": "^0.0.4",
20
+ "@hemia/common": "^0.0.7",
21
21
  "@hemia/app-context": "^0.0.6",
22
22
  "@hemia/trace-manager": "^0.0.9",
23
+ "@hemia/auth-sdk": "^0.0.9",
23
24
  "@types/express": "^5.0.5",
24
25
  "express": "^5.1.0",
25
26
  "inversify": "^7.10.4",
26
27
  "@types/jest": "^29.5.14",
27
28
  "@types/node": "^22.3.0",
28
29
  "@typescript-eslint/eslint-plugin": "^8.5.0",
30
+ "@types/multer": "^2.0.0",
29
31
  "class-transformer": "^0.5.1",
30
32
  "events": "^3.3.0",
31
33
  "jest": "^29.7.0",
@@ -34,7 +36,8 @@
34
36
  "rollup-plugin-typescript2": "^0.36.0",
35
37
  "ts-jest": "^29.2.5",
36
38
  "ts-node": "^8.9.0",
37
- "typescript": "^5.5.4"
39
+ "typescript": "^5.5.4",
40
+ "multer": "^2.0.2"
38
41
  },
39
42
  "author": "",
40
43
  "license": "ISC",
@@ -45,6 +48,10 @@
45
48
  "class-transformer": "^0.5.1",
46
49
  "express": "^5.0.0",
47
50
  "inversify": "^7.0.0",
48
- "reflect-metadata": "^0.1.13"
51
+ "reflect-metadata": "^0.2.2",
52
+ "multer": "^2.0.0"
53
+ },
54
+ "dependencies": {
55
+
49
56
  }
50
57
  }